看看这个执行计划:http
://sdrv.ms/1agLg7K
不是估计的,是实际的。从大约30 分钟的实际执行中。
选择第二条语句(占用总执行时间的 47.8%——大约 15 分钟)。
查看该语句中的顶部操作 – View Clustered Index Seek over _Security_Tuple4。该操作花费了语句的 51.2%——大约 7 分钟。
该视图包含大约 0.5M 行(作为参考,log2(0.5M) ~= 19 - 考虑到索引树节点大小为 2,仅 19 步,实际上可能更高)。
该运算符的结果是零行(与估计不匹配,但暂时不要介意)。
实际执行 - 零。
所以问题是:哔哔声怎么可能需要七分钟?!(当然,我该如何解决?)
编辑:关于我在这里问的一些澄清。
我对一般性能相关的建议不感兴趣,例如“查看索引”、“查看大小”、“参数嗅探”、“不同数据的不同执行计划”等。
我已经知道了所有这些,我可以做到所有这些分析我自己。
我真正需要的是知道什么会导致一个特定的聚集索引搜索如此缓慢,然后我可以做些什么来加快它。
不是整个查询。
不是查询的任何部分。
只是一个特定的索引搜索。
结束编辑
还要注意第二个和第三个最昂贵的操作是如何分别在 _Security_Tuple3 和 _Security_Tuple2 上查找的,它们只需要 7.5% 和 3.7% 的时间。同时,_Security_Tuple3 包含大约 280 万行,是 _Security_Tuple4 的六倍。
另外,一些背景:
- 这是该项目中唯一一个行为不端的数据库。有几十个相同模式的其他数据库,它们都没有出现这个问题。
- 第一次发现这个问题时,发现索引99%是碎片化的。重建索引确实加快了速度,但并不显着:整个查询在重建前用了 45 分钟,在重建后用了 30 分钟。
- 在使用数据库时,我注意到像“select count(*) from _Security_Tuple4”这样的简单查询需要几分钟时间。怎么回事?!
- 然而,他们在第一次运行时只用了几分钟,然后就瞬间完成了。
- 问题不连接到特定的服务器,也不连接到特定的 SQL Server 实例:如果我备份数据库然后在另一台计算机上恢复它,行为保持不变。