我们有一个使用以下分区函数在 STATUS 列上分区的分区表。因此,一个表将总共有两个分区,并且根据分区方案,两个分区都将进入不同的文件组。
CREATE PARTITION FUNCTION PART_FN_STATUS(INT) AS RANGE RIGHT FOR VALUES (1000)
注意: 根据业务逻辑,状态不能大于 1000。1000 是最大值。
我们在状态列上也有一个非聚集索引,它是一个对齐分区索引,即在状态列上分区。
当我运行以下查询并观察实际执行计划时,我有以下问题:
SELECT COUNT(*) FROM ORDERS WHERE STATUS <> 1000
- 在 NCI Seek 上,当我将鼠标悬停在它上面时,我可以看到“Actual Partition Count”为 2。那么为什么它不进行分区消除呢?
- 在相同的工具提示中,当我检查估计/实际读取的行数时,它实际上是 1 个分区的计数。所以看起来分区消除发生了?
- <> 是一个 Non-Sargable Operator,那么如何在 NCI 上发生 SEEK 呢?
- Non-Sargable Operator 可以进行分区消除吗?
任何帮助,将不胜感激。
对,但是...
您的查询提出了一个不好的问题。照原样,优化器不知道值 1001 是否存在于表中。谓词
<> 1000
并不意味着“1000 以下的所有内容”,除非您提供更多信息。设置
修复一:约束
检查约束可以提供帮助,但是...
您需要提防获得琐碎的计划/简单的参数化。如果您的文字值通过简单的参数化替换为参数,则需要在查询中添加一些内容以避免发生这种情况,如下所示:
修复二:破解函数
如果您想手动将优化器定向到分区,您可以像这样查询表以避免碰到不必要的分区: