SQLServer 列存储索引的性能问题:“Where OR”将影响谓词下推

Posted

技术标签:

【中文标题】SQLServer 列存储索引的性能问题:“Where OR”将影响谓词下推【英文标题】:Performance Issue of SQLServer Columnstore Index: "Where OR" will influence predicate pushdown 【发布时间】:2021-07-08 10:09:44 【问题描述】:

在SQL Server中,我有一个使用列存储索引的表,需要做一些聚合步骤,但是如果where子句包含“或”,谓词下推就会消失,我不知道为什么,有人对此有建议?例如,

在此查询文本中:

select sum(num) from Fact where date = '2021-06-02' and NUMF = 23

谓词下推将完美运行。但是如果我在 where 子句中添加一个“OR”,比如:

select sum(num) from Fact where date = '2021-06-02' or NUMF = 23

谓词下推不起作用,查询计划将扫描所有列存储索引,非常耗时。

这是 SQLServer 的一个特性吗?还是错误?

【问题讨论】:

性能如何? select sum(num) as num from ( select sum(num) as num from Fact where date = '2021-06-02' union all select sum(num) as num from Fact where NUMF = 23 and date <> '2021-06-02' ) t(假设 date 不可为空) @MartinSmith 感谢您的回复,确保此查询文本的性能很好,谓词有效,但有时查询文本会非常复杂,很难修改它以使用“UNION ALL”,例如: select sum(num) from Fact where date = '2021-06-02' or NUMF = 23 or column1 = 1 or column2 = 2 or column = 3 or column4 = 4. 所以,我认为这是一个好主意使用“union all”,但扩展性不够好。 【参考方案1】:

同一列上的 OR 谓词被下推,but when you use an OR predicate across different columns it can't be pushed down。 UNION ALL 解决方法也在该帖子中突出显示。如果您考虑一下您是如何实现它的,那是有道理的:columnstore 一次处理一列数据。

列式处理速度快的一个原因是您一次只对单个列进行操作,并且您会跟踪该列中符合该列上的谓词的行。完成所有谓词评估后,您可以返回聚合列中的行并计算聚合。

因此,在同一列上评估 OR 谓词很容易,如果您有 AND 谓词,您可以更新行列表。如果一行不符合后面的谓词,您始终可以将其从列表中删除。但是,如果您在多个列上有 OR 谓词和几个 AND 谓词,则评估顺序真的很重要,您可能需要多次重新访问同一列,所以我认为实现成本太高,无法在存储引擎中发生。我认为全 OR 谓词下推应该是可行的,尽管它可能会增加段消除的复杂性。

【讨论】:

以上是关于SQLServer 列存储索引的性能问题:“Where OR”将影响谓词下推的主要内容,如果未能解决你的问题,请参考以下文章

列存储索引中列的顺序在 SQL Server 2012 中是不是重要

列存储聚集索引 - 死锁问题 (SQL Server)

创建带包含列的索引 sqlserver

SQL Server 列存储索引更新/插入存储过程

SqlServer的三个索引简单说明及其使用

Azure SQL、聚集列存储索引、“TOP”性能