我想知道 MS SQL Server 中未使用的索引。通过索引使用 DMV,我可以识别尚未用于搜索、扫描或查找的索引。
但是我从 Oracle 了解到,在执行计划中可能不会以这种方式使用索引,但是它仍然可以为 (Oracle) 优化器提供统计信息/基数信息。这种贡献没有以同样的方式进行监控。
所以我想知道在 MSSQL 中索引是否可以产生类似的积极效果,即使它没有直接使用(在代表性时间范围内)?具体来说,如果它可以比列统计更好(即删除索引是有害的)。
我在任何索引调优文章中都没有看到这个,所以我假设 MSSQL(直到 2017 年)没有这个概念,对吗?
是的,即使基础索引未用于访问计划中的数据,基于索引的统计信息也可用于帮助创建查询计划。考虑到查询优化器在创建查询计划时可能会考虑许多不同的查询计划和数据访问路径。编译的查询计划可能最终不使用所考虑的索引之一。这当然并不意味着任何受益于该索引统计信息的查询计划都需要失效,对吧?
一个例子也可能有帮助。首先,我将大约 650 万行放入堆中:
接下来,我将在其中一列上创建一个索引,并查看自动创建的统计对象的直方图。
这是直方图:
根据统计数据,表中有 5806440 行的值为 1
INDEXED_COLUMN
。现在考虑这个查询:查询优化器有几个不同的数据访问路径。对于如何计算聚合,它也有一些选择。为聚合选择算法的考虑因素之一是数据的基数估计。这是查询计划的屏幕截图:
请注意,即使索引未用于访问数据,估计值也与直方图完全匹配。较新版本的 SQL Server 会显示在查询计划优化期间考虑了哪些统计信息。您可以看到使用了与索引关联的统计信息:
但是,
sys.dm_db_index_usage_stats
dmv 不报告索引上的任何最终用户活动。