ID
我的数据库当前在每个表的列上都有一个主键/聚集索引。然而,连接到数据库的应用程序总是在查看定义为:
SELECT * FROM Table WHERE DeletedDate IS NULL
最好将 添加DeletedDate
到聚集索引,还是将非聚集索引DeletedDate
作为包含项更好?
ID
我的数据库当前在每个表的列上都有一个主键/聚集索引。然而,连接到数据库的应用程序总是在查看定义为:
SELECT * FROM Table WHERE DeletedDate IS NULL
最好将 添加DeletedDate
到聚集索引,还是将非聚集索引DeletedDate
作为包含项更好?
既然我们说的是聚簇索引,仅仅因为你定义了 CI 键列为
ID
,你仍然有DeletedDate
索引的叶数据页中的数据。这就是聚簇索引的本质:它是表数据。因为您通常有如下查询:
您可能会受益于过滤索引。
我没有在此处明确放置键列(以及通过使用
INCLUDE
子句的非键列),因为您没有发布表的 DDL。正如我在上面对您的问题的评论中一样,键列(不仅是列,还有列的顺序)的选择在很大程度上取决于您的工作量和将使用该索引的典型查询。
如果您希望覆盖查询,则需要确保索引满足查询所需的所有数据。更不用说,如果您还有其他
WHERE
子句(除了NULL
检查DeletedDate
)或要考虑加入,那么关键列的顺序可能是扫描或查找之间的决定性因素。即使它被过滤,并且根据索引中的数据量,损失也可能相当大。Clustered index key
表现最好的是独特的、狭窄的、静态的和不断增长的。因此,在这种情况下,包含 DeletedDate 实际上会导致聚集键变为非唯一非静态(假设可以更改 DeletedDate 值)。INCLUDE
非聚集索引中的 可用于覆盖查询而无需对表执行键查找。但是,由于 INCLUDE 列仅存储在索引叶级别,因此它无助于搜索查询谓词的值(在本例中为 NULL)DeletedDate 的A
non-clustered index key
允许对满足谓词 (NULL) 的记录范围进行更有效的搜索。过滤的非聚集索引可以进一步缩小子集(仅 NULL 记录)并为非聚集索引提供更好的性能和存储。根据您的描述显示查询返回具有单个谓词的表中的所有列,您可以使用 为 DeletedDate 创建一个过滤的非聚集索引键
WHERE DeletedDate IS NULL
。对其进行测试并检查执行计划。