“估计的执行次数”被夸大了
Posted
技术标签:
【中文标题】“估计的执行次数”被夸大了【英文标题】:"Estimated Number of Executions" is inflated 【发布时间】:2016-11-07 14:39:00 【问题描述】:我有一种情况,我认为由于一些不正确的估计,选择了较慢的查询计划而不是较快的查询计划。但是,我无法弄清楚错误估计的来源。下面显示的是更快的计划,由于 Index Seek 的估计成本为 123,因此未选择该计划。实际上,成本并不像您从实际执行次数和估计执行次数之间的差异中看到的那样高。我的理解是执行次数是由嵌套循环顶部的行数驱动的。如您所见,估计的行数为 4878,与实际非常接近。但是底部输入的估计执行次数是 61110,这还差得很远。 FWIW,我已经用全扫描更新了所有表的统计信息,并且 1.22 Estimated Rows 是正确的(对于每次执行)。
61110 号码是从哪里来的,有什么办法可以解决吗?
查询如下所示:
SELECT
Top.Pk
FROM
Top
LEFT JOIN Bottom ON Bottom.Fk = Top.Pk
WHERE
Top.Date < GETUTCDATE()
AND Bottom.Fk IS NULL
【问题讨论】:
我忘了说,顶表是一个索引视图,以防万一。 您需要提供有关实际查询和表的更多详细信息。统计数据只是基数估计的一个方面。列表中的下一个将是您的搜索和加入条件实际上是什么。一个常见问题是优化器无法将连接条件与实际表内容相关联,因此您仅根据将匹配的行数的表大小来进行即时估计。另一个问题是一个内容非常不均匀的表,在特定匹配项上实际上可能有 60.000 个结果行,优化器都知道。 在这种情况下,它加入了 GUID。顶部表中的 PK 到底部的 FK。这是 seek 的唯一谓词。关于同质,我认为这就是统计的重点?无论如何,估计的行数是正确的(在特定匹配中没有 60,000 个结果行,有 1.22 个)。问题是估计的执行次数,我认为这是由顶部输入驱动的(根据截图中嵌套循环的描述)。 “关于同质,我认为这就是统计数据的重点?”是的,但是您必须了解,如果(比如说)您在另一个表中有一行包含 10.000 个对应行,而另一行包含 2 个,则优化器仍然无法提前知道您的查询是什么情况即使有完美的统计数据,也会碰巧命中。计划仍需提前编制,不能基于将实际流过的数据。您是对的,1.22302 的估计值在外推到实际结果时似乎或多或少是正确的,因此这不是问题。 我已添加查询。我明白你所说的关于同质数据的内容,但这里不是这种情况。问题不在于统计数据被夸大了(我不相信)。这会影响估计的行数。在这种情况下,估计的行数是正确的,并且与实际情况非常吻合:实际执行数 (4813) * 估计行数 (1.22) ~= 实际行数 (5205)。问题是估计的执行次数,我不知道它是从哪里来的。据推测,它将来自顶部的 Esitmated Number of Rows。 【参考方案1】:虽然我仍然不完全理解这里的执行计划向我们展示了什么,但事实证明这个问题的特定实例可以通过在索引视图上指定 WITH (NOEXPAND)
来解决,从而强制优化器考虑索引在索引视图上(我认为它已经在执行计划中执行,但显然不是)。
【讨论】:
以上是关于“估计的执行次数”被夸大了的主要内容,如果未能解决你的问题,请参考以下文章
使用 BigQuery 提取命中级别数据时,Google Analytics 指标被夸大了