sql - 查看聚集索引 查找超过 50 万行需要 7 分钟

标签 sql sql-server performance indexed-view indexed-views

看一下这个执行计划:http://sdrv.ms/1agLg7K
这不是估计的,是实际的。从实际执行来看,大约花费了30 分钟

选择第二条语句(占用总执行时间的 47.8% – 大约 15 分钟)。
查看该语句中的顶部操作 – View Clustered Index Seek over _Security_Tuple4。 该操作花费了语句的 51.2%——大约 7 分钟。

该 View 包含大约 0.5M 行(仅供引用,log2(0.5M) ~= 19 – 仅 19 个步骤,因为索引树节点大小为 2,实际上可能更高)。
该运算符的结果为零行(与估计不匹配,但现在不用介意)。
实际执行次数为零。

所以问题是:哔哔声怎么可能需要七分钟?! (当然,我该如何解决它?)


编辑:对我在这里提出的问题进行一些澄清
我对一般性能相关建议感兴趣,例如“查看索引”、“查看大小”、“参数嗅探”、“不同数据的不同执行计划”等。
我已经知道所有这些,我可以自己进行所有此类分析。

我真正需要的是知道什么可能导致某个特定的聚集索引搜索速度如此之慢,然后我可以采取什么措施来加快速度

不是整个查询。
查询的任何部分。
只是寻找一个特定的索引。
结束编辑


还要注意第二和第三最昂贵的操作是如何分别在 _Security_Tuple3 和 _Security_Tuple2 上查找的,它们只花费 7.5% 和 3.7% 的时间。同时,_Security_Tuple3 包含大约 280 万行,是 _Security_Tuple4 的六倍。

另外,一些背景:

  1. 这是该项目中唯一出现问题的数据库。 还有几十个具有相同架构的其他数据库,但没有一个出现此问题。
  2. 第一次发现这个问题时,发现索引 99% 都是碎片。 重建索引确实加快了速度,但并不显着:整个查询在重建前花费了 45 分钟,重建后花费了 30 分钟。
  3. 在使用数据库时,我注意到像“select count(*) from _Security_Tuple4”这样的简单查询需要几分钟的时间。 WTF?!
  4. 但是,第一次运行只花了几分钟,之后就很快了。
  5. 问题是连接到特定服务器,也未连接到特定 SQL Server 实例:如果我备份数据库,然后在另一台计算机上还原它,行为保持不变。<

最佳答案

首先我想指出一个小小的误解:虽然据说删除语句占用了整个执行时间的近 48%,但这并不一定意味着它占用了所需时间的 48%;事实上,在查询计划的该部分中分配的 51% 绝对不应该被解释为占用整个操作的“一半时间”!

无论如何,根据您的评论,“第一次”对表执行 COUNT(*) 操作需要几分钟,我倾向于说您遇到了与所述表/ View 相关的 IO 问题。就我个人而言,我不太喜欢物化 View ,因此我对它们以及它们内部的行为方式没有真正的经验,但通常我会认为碎片正在对底层存储系统造成损害。第二次运行速度快的原因是,从缓存访问页面比从磁盘获取页面要快得多,尤其是当页面遍布各处时。 ( View 中是否有任何(最大)字段?)

无论如何,要找出是什么花了这么长时间,我建议您宁愿将此代码从当前所在的触发器中取出,“伪造”插入和删除的表,然后尝试再次运行查询,添加时间戳和/或使用诸如 SQL Sentry Plan Explorer 之类的程序来查看每个部分真正花费的时间(当您从程序内运行脚本时,它有一个持续时间列)。 很可能你看错了部分;经验表明,成本和实际执行时间并不总是像我们想象的那样相关。

关于sql - 查看聚集索引 查找超过 50 万行需要 7 分钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18597663/

相关文章:

java - 这是打印二维数组最快的方法吗?

MySQL如何对表的最低值(value)/价格进行排序,并且只显示最低的名称?

sql - 相当于 SQL Server INSERTED 和 DELETED 表的 Oracle

sql-server - 如何在VB.NET中制作一个可以安装SQL Server Express Edition的安装程序?

sql-server - sql 备份文件和文件组选项已禁用

java - Hibernate 中的 beginTransaction 是否分配新的数据库连接?

performance - 负载测试软件

mysql - 有没有办法按与其子记录关联的最早日期对父记录进行排序?

mysql - SQL中如何将两列合并为单列?

mysql - 如果不存在具有类似特征的其他用户,则从 MySQL 表中删除用户