SQL Server非聚集索引永远不会出现在执行计划中

时间:2011-02-09 18:12:06

标签: sql-server indexing sql-execution-plan query-performance

我有一个名为tbl_event的数据库表,其中非聚集索引IDX_Event_FolderIDX_Event_Time定义为:

CREATE NONCLUSTERED INDEX [IDX_Event_Folder] 
ON [dbo].[tbl_event]([nobjectid] ASC)

CREATE NONCLUSTERED INDEX [IDX_Event_Time] 
ON [dbo].[tbl_event]([tetime] ASC)

我运行了以下简单查询,并直接在下面显示了执行计划:

查询1:

SELECT * 
FROM tbl_event 
WHERE tbl_event.nobjectid = 1410000
ORDER BY tetime

Execution Plan for Query 1

查询2:

SELECT * 
FROM tbl_event 
WHERE tbl_event.nobjectid = 1410000

Execution Plan for Query 2

我的问题是,为什么 nobjectid 的索引从未被使用过?我希望在这些select语句的where子句中指定nobjectid时会有索引搜索或扫描。我对这种分析的理解不正确吗?

3 个答案:

答案 0 :(得分:3)

  

为什么nobjectid上的索引永远不会   利用?我希望有   当nobjectid时索引搜索或扫描   在where子句

中指定

一种常见的误解!

有一点是:因为您正在使用SELECT *,所以您需要表格中的所有数据。所以最后,SQL Server必须返回实际的数据页并获取所有值。

当索引搜索发生并找到命中时,在这种情况下,SQL Server必须进行书签查找 - 这是一项相当昂贵的操作。

由于这些操作相当昂贵,SQL Server会尽量避免使用它们 - 因此在很多情况下,将使用表扫描,因为最终,这比寻找nc索引然后更快书签查找。

要检查的要点:

  • 选择性如何成为nobjectid列?这个听起来像一个或多或少独特的ID - 这将是好的。如果碰巧列上的索引不是很有选择性,那么查询优化器通常会忽略它(因为它必须检查太多行,所以最后表扫描更快)

  • 表中有多少?对于小表(少于几千行),从go go开始进行表扫描通常要快得多

另外,从你的第一个带有“RID堆查找”的执行计划,我得出结论,你没有桌面上的聚集索引 - 立即添加一个 !!没有聚簇键(因此具有而不是聚簇表)也会减慢大量操作并降低非聚集索引的有效性。

尝试在“NUSE”列上添加聚集索引:

  • 独特
  • 稳定
  • 不断增加

INT IDENTITY是一个完美的候选人 - UNIQUEIDENTIFIER或非常宽的复合列是最差的。阅读有关在Kimberly Tripp's blog

选择正确聚集索引的所有内容

答案 1 :(得分:2)

你在评论中说,目前表中有18325170行,其中只有约30个有nobjectid = 1410000。

即使您的IDX_Event_Folder索引已被禁用,我也无法相信SQL Server会为该行数量选择此计划,并且行厚度表明它认为它正在处理可能是1行而不是18325170!

Plan

所以我很确定您必须禁用自动更新统计信息?如果是这样,您将需要手动更新统计信息(或最好启用此选项)

答案 2 :(得分:1)

有几个重叠的事情正在进行中

  • 您的SELECT *表示“给我所有专栏”。优化器决定扫描表格更有用。
  • 唯一有用的索引是用于订购的tetime。它这样做,然后钻进桌子。
  • 您没有聚集索引(RID /堆查找显示)
  • nobjectid索引缺乏唯一性无济于事:它意味着完整的索引扫描。 o为什么在与SELECT *结合使用时使用索引?

如果你有这个,那么将使用索引(作为扫描)

SELECT nobjectid
FROM tbl_event 
WHERE tbl_event.nobjectid = 1410000

或者说,新索引最有可能被使用

CREATE NONCLUSTERED INDEX [IDX_Co,bined] 
ON [dbo].[tbl_event]([nobjectid] ASC, tetime)

SELECT nobjectid, tetime
FROM tbl_event 
WHERE tbl_nobjectid = 1410000
ORDER BY tetime

我建议你阅读这些文章

这些文章也应该涵盖聚集索引的缺失