我的执行计划试图欺骗我吗?

时间:2009-12-29 21:11:05

标签: sql sql-server sql-server-2005 sql-execution-plan

我正在尝试加快我所拥有的长时间运行的查询(运行大约需要10分钟......)。为了追踪查询的哪一部分花费了我最多的时间,当我运行它时,我包含了实际执行计划,并发现一个占55%的特定部分(下面的屏幕截图)

alt text http://img109.imageshack.us/img109/9571/53218794.png

这对我来说似乎不对,所以我在此问题部分之前和之后添加了Print '1'Print '2'。当我运行查询仅仅17秒然后取消它时,我假设的1和2打印输出意味着它在前17秒内通过该部分。

alt text http://img297.imageshack.us/img297/4739/66797633.png

我在这里做错了还是我的执行计划误导了我?

4 个答案:

答案 0 :(得分:1)

perfmon的指标也有助于弄清楚出现了什么问题......你可能会遇到一些与你的tempDB所在的驱动器有关的严重IO问题。另外,运行跟踪并查看CPU&实际运行的IO。

要查看的好的perfmon指标是磁盘队列长度(平均和写入)。

如果您无法访问perfmon或不想跟踪事物,请在查询开头使用“SET STATISTICS IO ON”并允许它完成...不要停止它。仅仅因为执行计划表明它正在接管成本并不意味着它将运行一半的查询时间......它可能会更多(或更少)。

答案 1 :(得分:1)

它说Query 10: Query cost (relative to the batch): 55%。 100%肯定它是你用Print语句包围的批次中的第10个声明吗? INSERT ... INTO#mpProgramSet2可以执行多次,有时会在17秒内执行其他时间5分钟,具体取决于选择/插入了多少数据?

作为旁注,您应该使用SET STATISTICS TIME ON而不是打印,这将为您提供批处理中每个语句的准确编译/时间和执行时间。

答案 2 :(得分:0)

我们需要完整的查询才能了解正在发生的事情;但我可能会开始将MAXD​​OP设置为1,以限​​制它运行的处理器数量。

请注意,由于锁定等原因,有时查询仅限于1个处理器。

此外,您可以尝试将NOLOCK添加到您的任何选择中,这些选择可以消除脏读。

答案 3 :(得分:0)

我不相信打印'1'和'2'会证明已执行的内容和未执行的内容。我做同样的事情,但我不会依赖它作为证据。您可以从第一个插入查询中打印@@ rowcount - 这将表明插件已经发生。

虽然计划表明查询可能需要55%的成本,但可能不是执行时间的55%,尤其是在缓存查询结果的情况下。

打印@@ rowcount的另一个好处是将实际行数与估计行(51K)进行比较。如果它们差别很大,那么您可以调查索引的统计信息。