覆盖索引的有用性

时间:2013-02-19 19:35:05

标签: sql sql-server indexing covering-index

我有一个在多个表上执行连接的查询。我对表的外键和主键上的聚簇索引有非聚集索引。在分析查询计划时,我认为查询优化器正在选择所有表上的聚簇索引扫描,或者在某些情况下选择非聚集索引扫描和密钥查找的组合来获取其他非键列。为了解决这个问题,我在非聚集索引中包含(覆盖)此查询中所需的非键列。因此,我可以看到非聚集索引搜索/扫描按预期执行。

现在我的问题是,如果我有其他查询要求许多其他非键列成为结果集的一部分,那么我可能最终将所有列添加(包含)到非聚集索引以提高性能所有查询。这会是一个好主意吗?

感谢。

2 个答案:

答案 0 :(得分:1)

非常了解您的用法。为您可能查询的所有内容添加索引会非常容易,但与所有内容相比,这是一种权衡取舍。每个索引都会花费您的时间和存储空间 - 因此它可能会减慢您的插入/更新速度,并且您索引的成本越高。

如果您的使用非常有利于读取写入,那么一切都很好,您需要做的就是支付一些存储费用。如果你的写作也需要不错的表现,那么你所能做的就是了解你的应用程序并索引你最重要的东西。

我强烈推荐“内部sql服务器”系列丛书(Kalen Delaney等人) - 大量阅读可以通过,但我保证他们会帮助你理解你所做的权衡。

答案 1 :(得分:0)

听起来你包含了WHERE子句所需的列,结果你得到了索引。

您还可以包含SELECT列表中的列,这样可以获得不同的好处。如果您的索引包含查询所需的所有字段,包括SELECT列表,那么查询结果可以直接从索引中返回,并且它根本不必返回到表记录。

当然,UPDATE,INSERT和DELETE操作会包含索引构建的额外成本。

您可以运行SQL Server Management Studio工具> SQL Server Profiler获取当前数据库活动的示例。然后,您可以将其提供给工具>数据库引擎优化顾问。如果您有很多INSERT和UPDATE活动,Tuning Advisor可能会建议删除一些索引。如果您的活动主要是SELECT语句,则可能会建议其他索引。

我发现数据库引擎优化顾问经常建议覆盖许多列的索引,例如您所描述的。我有时会在这个问题上继续提出建议,但通常会将索引限制在键和条件列中,除非特定查询存在特定的性能问题。