聚集索引扫描

Posted

技术标签:

【中文标题】聚集索引扫描【英文标题】:Clustered Index scan 【发布时间】:2014-01-24 21:31:21 【问题描述】:

当我只选择 Id 时,我看不到,但是当我选择 XML 列时,我看到。

索引不是只用于Where子句而不用于select子句吗?

declare @LenderID int = null,
@LenderCode varchar(64)= null
--Add Lender Search as in Lender Maintenance
if @LenderID is not NULL
  Select @LenderCode = CODE_TX from LENDER 
     where ID = @LenderID and PURGE_DT IS NULL

 declare @StartDate datetime2 = '1/22/2014 12:00:00 AM', 
         @EndDate datetime2 = '1/24/2014 12:00:00 AM'
 select rh.id 
 from  REPORT_HISTORY rh
 where 
 (
   (@StartDate is NULL or @EndDate is NULL)
 or
   (RH.CREATE_DT between  @StartDate and @EndDate)
  )
and
(
   RH.LENDER_ID = @LenderID
or 
   @LenderCode is NULL
)

同样令人惊讶的是,数据库无法处理像 @StartDate 为 NULL 或 @EndDate 为 NULL 这样的子句并进行索引扫描,如果该字段作为 null 传递,它应该忽略该字段。

提前致谢

【问题讨论】:

你能把两个实际执行计划贴在某个地方吗? 生成巨大的xml,我试试 你是如何定义你的聚集索引的?您可以发布定义它的脚本吗?实际执行计划的屏幕截图也会有所帮助。 【参考方案1】:

答案可能取决于查询优化器对您的表和索引的看法,其中包括行大小和适用的统计信息。

索引并不神奇,而且它们并不总是有帮助。如果 SQL Server 选择使用索引,它应该能够有效地在索引上查找索引中包含的任何内容。但出于同样的原因,如果您询问索引未涵盖的任何信息,则该数据将位于其他位置(在磁盘或内存中),并且需要使用聚集索引进行交叉引用。

因此,当出现查询时,SQL Server 需要做出假设并猜测最佳查询计划。索引查找将返回多少行?在该过程中需要读取多少数据,而如果它刚刚命中聚集索引,则需要读取多少数据?需要执行多少次聚集索引查找才能获取更多数据?

那么,要检查的事情是:您的索引是否涵盖了 XML 列?如果不是,您的查询将返回多少行与主表中的行数?你的统计数据是最新的吗?如果你真的想要,你可以使用查询提示来强制使用特定的索引,但你绝对应该先看看这些其他的东西。

【讨论】:

以上是关于聚集索引扫描的主要内容,如果未能解决你的问题,请参考以下文章

聚集索引扫描

SQL SERVER 聚集索引 非聚集索引 区别

为啥Sql Indexed View总是使用聚集索引

07.索引-非聚集索引-Key Lookup &RID Lookup

SQL Server之索引解析

99.索引-TODO