我正在编写一个存储过程来获取销售报告的数据。查询是这样的:
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环境非常慢,我看了执行计划。首先,我看了一下Estimated计划。它看到SecondQuery花了很长时间,我意识到u1.NONindexedField没有索引,估计占总成本的97%。 但后来我看了一下Actual计划,它说FirstQuery占总成本的100%。我检查了在估计计划上计算的估计行数,并且很多地方估计很少的行,其中实际计划显示大约一百个(100K)。我以为这是因为缺少索引的字段位于没有那么多行(17K)的表中,但我仍然创建了索引。令我惊讶的是,查询时间从500秒减少到15秒。 所以,我的问题是......为什么执行计划有这么大差异,实际计划怎么样呢?我知道估计的计划并不是指“对计划的估计”,而是“计划有估计行数”,但这并不能解释其中的差异,并且无法解释为什么实际计划告诉我所有成本是在一个不需要优化的查询...
顺便说一下,我比较了相对时间,第二个查询确实占用了总执行时间的97%左右。
感谢阅读!
答案 0 :(得分:0)
如果实际计划没有实现,这可能是由过时的统计数据引起的。
您是否尝试更新查询中表格的统计信息。
如果统计信息已过期,则可能导致执行计划关闭。如果没有更新的统计信息,您的查询可能效率很低。
更新统计信息的语法是:
update statistics tablename;
尝试更新统计信息,看看您是否获得了更准确的执行计划。