0

我正在写一个存储过程,以获取销售报告的数据。查询是这样的:SQL执行计划 - 预计计划似乎比实际计划更准确

INSERT INTO @FirstQuery 
SELECT t1.*, t2.* 
    FROM t1 
     LEFT JOIN t2 ON t1.idT1 = t2.idT1 
     LEFT JOIN t3 ON t3.idT2 = t2.idT2 
WHERE t1.nonIndexedField = @parameter1 
    AND (t2.idT2 IS NULL 
      OR 
      (@parameter2 = 'XXX' AND t1.indexedField1 = @parameter3) 
      OR 
      (@parameter2 = 'YYY' AND t3.indexedField1 = @parameter3) 
     ) 

有了这些成绩,我然后填写第二个表变量:

INSERT INTO @SecondQuery 
SELECT u1.*, u2.* 
    FROM u1 
     INNER JOIN u2 ON u2.idU1 = u1.idU1 
WHERE u1.NONindexedField in (SELECT someField FROM @FirstQuery) 

由于这是正对QA环境很慢,我看了执行计划。首先我看看了预计计划。它发现SecondQuery需要很长时间,我意识到u1.NONindexedField没有索引,估计占总成本的97%。 但后来我看了一下实际计划,它说FirstQuery的总收入是100%。我检查了在估计计划上计算出的估计行数,并且它估计了很多行,实际计划显示的行数很少(100K)。我认为这是因为缺少索引的字段在一个没有太多行(17K)的表中,但我仍然创建了索引。令我惊讶的是,查询时间从500秒减少到15秒。 所以,我的问题是......为什么这样的执行计划差异,以及实际计划如何实现?我知道估计的计划并不是真的意味着“对计划的估计”,而是“估计行数”的计划,但这并不能解释这种差异,并且不能解释为什么实际计划告诉我所有人成本是在一个查询,不需要优化...

顺便说一句,我比较相对时间和第二个查询确实需要大约97%的总执行时间。

感谢您的阅读!

回答

0

如果实际计划失败,可能是由于过时的统计数据造成的。

您是否尝试过更新查询中表格的统计信息。

如果统计数据过期,这可能导致执行计划关闭。如果没有更新的统计数据,您的查询可能会非常低效。

的语法用于更新统计是:

update statistics tablename; 

尝试更新的统计数据,看看你得到更准确的执行计划。

+0

感谢您的回复!我更新了所有表格的统计数据,并没有帮助。实际执行计划没有改变。 – 2012-04-10 14:50:19