SQL 执行计划 - 估计计划似乎比实际计划更准确

Posted

技术标签:

【中文标题】SQL 执行计划 - 估计计划似乎比实际计划更准确【英文标题】:SQL execution plans - Estimated plan seems to be more accurate than Actual plan 【发布时间】:2012-03-28 22:17:28 【问题描述】:

我正在编写一个存储过程来获取销售报告的数据。查询是这样的:

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%。我检查了根据估计计划计算的估计行数,在许多地方,它估计实际计划显示的行数很少,大约为 100 万 (100K)。我认为这是因为缺少索引的字段位于行数不多(17K)的表中,但我还是创建了索引。令我惊讶的是,查询时间从 500 秒减少到 15 秒。 所以,我的问题是......为什么在执行计划上会有如此大的差异,以及实际的计划是如何偏离的?我知道估计的计划并不真正意味着“计划的估计”,而是“具有估计行数的计划”,但这并不能解释差异,当然也不能解释为什么实际计划告诉我所有成本在于不需要优化的查询...

顺便说一句,我比较了相对时间,第二个查询确实占用了总执行时间的 97% 左右。

感谢阅读!

【问题讨论】:

【参考方案1】:

如果与实际计划相去甚远,这可能是由过时的统计数据造成的。

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

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

更新统计的语法是:

update statistics tablename;

尝试更新统计信息,看看您是否获得了更准确的执行计划。

【讨论】:

感谢您的回复!我为所有涉及的表更新了统计信息,但没有帮助。实际执行计划没有改变。

以上是关于SQL 执行计划 - 估计计划似乎比实际计划更准确的主要内容,如果未能解决你的问题,请参考以下文章

Oracle固定SQL的执行计划---SQL Profile

使用执行计划进行 Sql 调优

万字长文详解HiveSQL执行计划

SQL Server 查找统计信息的采样时间与采样比例

SQL SERVER如何应用执行计划

“估计的执行次数”被夸大了