我有一个在多个表上执行连接的查询。我在表的外键上有非聚集索引,在主键上有聚集索引。在分析查询计划时,我发现查询优化器选择对所有表进行聚集索引扫描,或者在某些情况下结合非聚集索引扫描和键查找来获取其他非键列。为了解决这个问题,我在非聚集索引中包含(覆盖)了此查询中所需的非键列。因此,我可以看到非聚集索引搜索/扫描按预期执行。
现在我的问题是,如果我有其他查询需要许多其他非键列作为结果集的一部分,那么我最终可能会将所有列添加(包括)到非聚集索引中以提高所有查询的性能. 这是个好主意吗?
谢谢。
我有一个在多个表上执行连接的查询。我在表的外键上有非聚集索引,在主键上有聚集索引。在分析查询计划时,我发现查询优化器选择对所有表进行聚集索引扫描,或者在某些情况下结合非聚集索引扫描和键查找来获取其他非键列。为了解决这个问题,我在非聚集索引中包含(覆盖)了此查询中所需的非键列。因此,我可以看到非聚集索引搜索/扫描按预期执行。
现在我的问题是,如果我有其他查询需要许多其他非键列作为结果集的一部分,那么我最终可能会将所有列添加(包括)到非聚集索引中以提高所有查询的性能. 这是个好主意吗?
谢谢。
它非常了解您的使用情况。为您可能查询的所有内容添加索引真的很容易,但与所有内容一样,这是一个权衡。每个索引都会花费您的时间和存储空间 - 因此它可能会减慢您的插入/更新速度,并且索引越多,此成本就越高。
如果您的使用非常倾向于读取而不是写入,那么一切都很好,您需要做的就是支付一些存储费用。如果您也需要良好的写入性能,那么您真正能做的就是了解您的应用程序并索引您最重要的内容。
我强烈推荐“inside sql server”系列书籍(Kalen Delaney 等人)——阅读大量内容,但我保证它们会帮助您了解您所做的权衡。
听起来您包含了 WHERE 子句所需的列,因此您得到了索引搜索。
您还可以包含 SELECT 列表中的列,这会给您带来不同的好处。如果您的索引包含查询所需的所有字段,包括 SELECT 列表,那么查询结果可以直接从索引中返回,并且根本不需要返回表记录。
当然,UPDATE、INSERT 和 DELETE 操作包括索引构建的额外成本。
您可以运行 SQL Server Management Studio 工具 > SQL Server Profiler 来获取当前数据库活动的示例。然后,您可以将其提供给 Tools > Database Engine Tuning Advisor。如果您有很多 INSERT 和 UPDATE 活动,Tuning Advisor 可能会建议删除一些索引。如果您的活动主要是 SELECT 语句,则很可能会建议附加索引。
我发现数据库引擎优化顾问经常建议在许多列上覆盖索引,例如您所描述的。在这件事上,我有时会同意它的建议,但通常会将索引限制在键和条件列,除非特定查询存在特定的性能问题。