特定列的最佳索引通常使用IS NULL过滤?

时间:2014-09-26 16:20:24

标签: sql-server performance indexing

我对用于表格中特定列的最佳索引有点不确定。

我有一个[Deleted]列是DateTime,表示记录从系统“删除”的时刻(它是软删除,所以不删除物理记录本身​​)。

几乎所有命中该表的查询都会有一个'WHERE [Deleted] IS NULL'过滤器。我并不担心没有这个过滤器的查询的性能。

为此方案构建的最佳索引是什么?已过滤的索引WHERE [已删除]是否为空?定义的计算列的索引IsDeleted =已删除IS NOT NULL?我有点不确定。

2 个答案:

答案 0 :(得分:2)

正如您所说almost all the queries将包含此条款。我建议在您的表中添加BIT列,一旦删除一行(软删除)将其设置为1.还要将此Datetime列保留为Deleted_Datetime,以跟踪何时删除记录。

然后在该BIT字段上创建一个过滤索引,如

CREATE NONCLUSTERED INDEX NCIX_Deleted_Data
ON dbo.Table(Deleted)
WHERE Deleted = 0

Bit是最小的数据类型,并且在其上具有过滤索引将为您带来巨大的性能提升。

您也可以在Datetime列上创建此筛选索引。但逻辑是这样的情况下,sql server必须通过索引上的8个字节的数据来查看行是否被过滤。

然而,如果你有比特列sql服务器将不得不通过1字节的数据来过滤它或保持它。

较小的数据快速处理,更大的数据处理它的时间更多:)。

答案 1 :(得分:2)

这是一场失败的战斗。您可以为所有其他索引添加过滤器,请参阅filtered indexes。但是你将无法过滤聚集索引。

Deleted列上的过滤器对于NULL来说太没有选择性,所有查询都会点击index tipping point。并且bit已删除的列更糟糕,选择性为0/1,总是被忽略。

我建议您调查partitioned views。您可以将当前数据存储在一个表中,将删除的数据存储在另一个表中,并在将两者联合起来的视图上操作。如果设计得当(这就是为什么阅读链接至关重要,要理解'正确'部分)这个方案工作正常,你永远不会扫描'冷'数据。

相关问题