【问题标题】:Should I include all of my columns from the select in my index?我应该在我的索引中包含来自选择的所有列吗?
【发布时间】:2015-04-25 02:24:57
【问题描述】:

我有一个查询需要一些时间才能运行,它看起来像这样。

Select a.ColumnA,a.ColumnB,a.ColumnC,a.CoulmnD,a.columnE,...b.ColumnH
from Table A a
  inner join Table B b
       on a.columnB = b.ColumnB
  Where a.columnA = @VariableA

现在它在表 A 上有一个像这样的聚集索引

Clustered Index on ColumnA

它在表 A 上也有一个像这样的非聚集索引

NonClustered Index on (ColumnA,ColumnB) include (ColumnC,ColumnD)

我是否也应该将 ColumnsE-G 添加到索引中?

【问题讨论】:

  • 能否包含执行计划
  • 索引中包含的列越多,使用该索引的成本就越高。大概您希望通过添加列来完全避免读取基表,但是如果表 A 足够大并且您的查询只命中了足够小比例的行,那么将额外的列排除在索引之外可能更便宜。执行计划可能会帮助您确定您是否处于该状态,但如果有任何不确定性,请测试
  • @ughai 我现在手头没有执行计划,但是成本最高的部分是 TableA 上的聚集索引扫描,输出是 ColumnA-G。这让我感到困惑,因为我认为它应该使用非聚集索引进行非聚集索引搜索,因为我的 where 子句和连接条件都包含在索引中。
  • 它可能进行聚集索引扫描的原因是,如果优化器感觉返回的行太多,并且使用键查找的非聚集查找会更昂贵。 A列存储什么样的数据?该列是否存储大量不同的值,或者它是否具有大部分相似的数据?你的统计数据是最新的吗?涉及的变量太多,我们无法给您一个简明正确的答案
  • 这很有趣。列 a 是唯一列,但优化器选择聚集索引扫描而不是聚集索引查找。执行计划可能会有所启发

标签: sql sql-server indexing


【解决方案1】:

验证比较列数据类型参数在执行中看到索引扫描而不是预期的搜索时是否相同计划。

当数据类型不同时,SQL Server 必须首先将优先级较低的操作数转换为优先级较高的数据类型(例如,varcharnvarchar)。当它是必须转换的列值时,转换会阻止有效使用列上的索引,因为在进行比较之前必须转换每一行的列值。这被称为 non-sargable 表达式并阻止更有效的索引搜索

【讨论】:

    猜你喜欢
    • 2011-01-12
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 2012-03-31
    相关资源
    最近更新 更多