在运行了一个相当大的查询之后,执行计划给了我一个缺失的索引建议,其形式如下:
(时间戳) INCLUDE (CustomerID, EventID, ID, EmployeeID)
这似乎是一个覆盖索引(INCLUDE 列都是主键(ID)或外键)。但是,我的查询 WHERE 子句是按时间戳、客户 ID 和事件 ID 进行过滤的。我不知道为什么这些没有包含在索引的主要部分中。
所以我的问题是,使用上面建议的索引有什么不同,或者我认为是更好的选择;
(时间戳、客户 ID、事件 ID)包括(ID、员工 ID)
我的理解是,这仍将允许仅时间戳索引查找,但还将通过在主要部分中包含客户和事件 ID(已过滤)来进一步帮助我的查询。
我认为这与“主要”部分的宽度有关 - 仅供参考,时间戳是 datetime2(0),CustomerID 是 int,EventID 是一个字节。
我目前正在测试这个,但这是一个巨大的表 - 超过 1,000,000,000 行 - 比较索引需要时间。那个,我想更多地了解这个。
谢谢。
可能Timestamp是非常有选择性的,甚至可能是独一无二的。因此,向键添加其他字段没有意义,它们只会增加键的大小而不会影响选择性。将它们作为 INCLUDED 列允许它们仅添加到叶页,从而节省索引的整体大小。
select top(1000) count(*) as cnt, Timestamp
from ...
group by Timestamp
order by cnt desc;
Run Code Online (Sandbox Code Playgroud)
以上返回什么?
所以我的问题是,使用上面建议的索引有什么不同,或者我认为是更好的选择......
优化器提出的缺失索引建议是机会性的,并且仅与相关的特定查询相关。优化器会经历一个索引分析阶段,在这个阶段它可能会注意到没有找到的覆盖索引。这些建议并非旨在替代代表完整工作负载的 DTA 会话,更不用说由熟练的数据库从业者基于对数据和关键查询的广泛知识进行适当的索引设计。
正如您所做的那样,应始终审查建议,以确保为所有查询创建一组最佳索引——而不是每个查询都覆盖索引,如果按照字面意思遵循建议,则可能会出现这种情况。
与使用INCLUDE列相比,扩大索引的键时自然会产生影响,其中一些已经被其他人注意到。我个人更喜欢INCLUDE在有用的地方明确使用聚类键。聚集索引可以更改,执行此更改的人员很少会检查是否有任何查询依赖于隐式行为。
将列更改INCLUDE为键也可能会影响更新查询计划(整体形状和万圣节保护要求),并且索引的键也可能发生变化时会产生日志影响。
我可能会选择像您所做的那样修改建议,但我会小心地验证受影响表的更新(= 插入/更新/删除/合并)查询计划。
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |