如何通过避免扫描空值来减少索引扫描

Posted

技术标签:

【中文标题】如何通过避免扫描空值来减少索引扫描【英文标题】:How to reduce index scan by avoid scaning null values 【发布时间】:2012-04-21 21:07:00 【问题描述】:

我正在使用 SQL Server 2008 R2,我想在非唯一、可为空的字段上添加非聚集索引。为了避免访问我的聚集索引,我的索引还将包含一列:

CREATE INDEX IX_My_Index 
ON MyTable (myBasicField) 
INCLUDE (myIncludedField);

myBasicField的实际数据中会有很多NULLs,我想知道是否有办法通过不扫描这些NULLs来提高性能,或者阻止存储NULL值在我的索引上。

提前致谢。

【问题讨论】:

我喜欢过滤后的索引答案。这只是另一回事。您可以将该数据放在具有 FK 关系的单独表中,然后完全消除空值(如果它为空,则 FK 表中没有行。)。如果两者都是聚集索引,则 PK 到 FK 连接非常快。 我想确认 Sql Server 确实在索引中包含 NULL(确实如此) - ms docs(来自 this answer) 【参考方案1】:

对于 SQL Server 2008 及更高版本,您可以使用过滤索引。查看intro blog post here - 语法为:

CREATE INDEX IX_My_Index 
ON MyTable (myBasicField) 
INCLUDE (myIncludedField)
WHERE myBasicField IS NOT NULL;

任何包含相同WHERE 子句的查询都可以利用这一点,如果您排除这样的 NULL 值,索引会小很多,因此性能会更好。

【讨论】:

+1 如果用户查询是 myBasicField IS NULL 那么你会得到一个全表扫描? @Blam:可能 - 取决于您的查询中可能存在的其他标准。如果myBasicField为NULL,那么这个索引肯定不会被使用。 感谢你们的快速回复。这就是我需要的 顺便问一下,我可以在 SQL Server 2005 中做类似的事情吗?我们有几个客户还没有升级,所以我也需要那里。 @zafeiris.m:不,很遗憾 - 这是 SQL Server 2008 中的新功能【参考方案2】:

您正在寻找过滤索引。见:

http://technet.microsoft.com/en-us/library/cc280372.aspx

【讨论】:

感谢您的快速回答 [我的声誉太少,无法投票给您,抱歉 :)]。我会检查一下并告诉你

以上是关于如何通过避免扫描空值来减少索引扫描的主要内容,如果未能解决你的问题,请参考以下文章

优化 MySQL 查询以避免扫描大量行

SQL 数据优化索引建suo避免全表扫描

SQL 数据优化索引建suo避免全表扫描

避免全表扫描的sql优化

优化 SQL 查询以避免全表扫描

mysql调优