看看这个执行计划:http://sdrv.ms/1agLg7K
这不是估计的,而是实际的。从实际执行大约 30分钟。
选择第二个陈述(占总执行时间的47.8% - 大约15分钟) 查看该语句中的top操作 - 查看Clustered Index Seek over _Security_Tuple4。 运营成本占声明的51.2% - 大约7分钟。
该视图包含大约0.5M行(作为参考,log2(0.5M)〜= 19 - 如果索引树节点大小为2,则仅仅19步,实际上可能更高)。
该运算符的结果是零行(与估计值不匹配,但现在不记得了。)
实际执行 - 零。
所以问题是:哔哔声怎么可能需要7分钟?! (当然,我该如何解决?)
编辑:对我在这里要求的内容进行了一些澄清。
我不对一般性能相关的建议感兴趣,例如“查看索引”,“查看大小”,“参数嗅探”,“不同数据的不同执行计划”等。 />
我已经知道了所有这些,我可以自己做那种分析。
我真正需要的是知道什么可能导致某个特定聚集索引寻求如此缓慢,然后我该怎么做才能加快。
不整个查询。
不查询的任何部分。
只是一个特定的指数寻求
结束编辑
另请注意第二和第三最昂贵的操作如何分别在_Security_Tuple3和_Security_Tuple2上进行搜索,它们只占7.5%和3.7%的时间。同时,_Security_Tuple3包含大约2.8M行,是_Security_Tuple4的六倍。
还有一些背景知识:
答案 0 :(得分:3)
首先,我想在这里指出一点误解:虽然据说删除声明占整个执行的近48%,但这并不意味着它需要48%的时间;实际上,在查询计划的那部分内部分配的51%绝对不应被解释为占用整个操作的“一半时间”!
无论如何,按照你的说法,第一次执行表格的COUNT(*)需要几分钟时间我倾向于说你有一个与所述表/视图相关的IO问题。就个人而言,我不太喜欢物化视图,因此我对它们没有真正的经验以及它们如何在内部表现,但通常我会建议碎片导致它对底层存储系统造成损害。它第二次快速工作的原因是因为从缓存中访问页面比从磁盘中获取页面要快得多,特别是当它们遍布整个地方时。 (视图中是否有(最大)字段?)
无论如何,为了找出花了这么长时间,我建议你把这个代码从它当前所在的触发器中取出,'假'一个插入和删除的表,然后尝试再次运行查询添加时间戳和/或者使用SQL Sentry Plan Explorer之类的程序来查看每个部分真正需要多长时间(当你从程序中运行脚本时它有一个持续时间列)。 很可能你正在看错了部分;经验表明,成本和实际执行时间并不总是像我们想的那样相关。
答案 1 :(得分:1)
观察包括:
这不是一个完整的分析,但它给你一些东西要看。
答案 2 :(得分:0)
费奥多尔,
首先:
问题没有连接到特定的服务器,也没有连接到特定的SQL Server实例:如果我备份数据库然后在另一台计算机上恢复它,行为将保持不变。
我假设您:a)在隔离环境中运行此查询,b)数据未发生变异。
这是对的吗?
第二:在这里发布您的CREATE INDEX脚本。你有一个有趣的FILLFACTOR吗? SORT_IN_TEMPDB?
第三:您的ParentId,ObjectId是哪种类型? int,smallint,uniqueidentifier,varchar?