覆盖索引的有用性



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

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

谢谢。

这在很大程度上是理解您的用法的一个例子。为您可能查询的所有内容添加索引确实很容易,但与所有内容一样,这是一种权衡。每个索引都需要花费时间和存储空间,因此它可能会减慢插入/更新的速度,而且索引越多,成本就越高。

如果你的使用非常喜欢读而不是写,那么一切都很好,你所需要做的就是支付一些存储费用。如果您也需要良好的写入性能,那么您真正能做的就是了解您的应用程序并为最重要的内容编制索引。

我强烈推荐"sql server内部"系列书籍(Kalen Delaney等人)——阅读量很大,但我保证它们会帮助你理解你所做的权衡。

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

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

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

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

我发现数据库引擎优化顾问经常建议覆盖多列的索引,如您所描述的。在这方面,我有时会赞同它的建议,但通常会将索引限制在键列和条件列,除非特定查询存在特定的性能问题。

最新更新