相同的数据和查询.有人在几秒钟内完成;其他时间结束



我正在使用AWS RDS Postgres v13.7

我有一个表,foo,约1m行。我运行一个查询,在CTE的2列上选择不同,之后是自连接,最后是选择计数(*)。

我克隆使用create table bar as (select * from foo)。我在这个表上运行相同的查询。

使用foo的查询挂起并且永远不会结束。使用bar的查询将在10秒内完成。我正在运行/启动它们并排,并尝试在另一个之前运行一个,所以它不是资源或查询问题的顺序;Foo永远不会结束,bar总是在几秒钟内结束。在下午的一段时间里,foo查询也会很快完成,所以可能有时间问题。

完全相同的数据和查询结果不同。

我打扫过了。解释两个表和查询是相同的。

当我尝试分解CTE时,对foo或bar的select distinct执行相同的操作,正如预期的那样。挂起的是foo上的self join

我已经读过这篇文章"相同的表,相同的查询,完全不同的执行时间";完全相同的查询和计划,但持续时间和总读取量不同。我知道参数嗅探,但是我不相信它们适用于我的情况

我的期望是foo查询应该运行得和bar查询一样快,或者它们的行为方式相同

在PostgreSQL中,VACUUM会回收死元组占用的存储空间,然后ANALYZE会更新统计数据,或者使用VACUUM ANALYZE回收存储空间并更新表的统计数据。

例句:

VACUUM ANALYZE foo;
-- now run your query

这看起来像是foo倾斜统计的问题。由Postgres设计的查询执行计划依赖于查询语义、可用索引、服务器配置等,但它也依赖于Postgres收集的关于数据的表统计(参见:https://www.postgresql.org/docs/current/view-pg-stats.html)。最后,基于启发式设计查询计划。

我猜对于您的情况,可能是foo可能已经存在较长时间,然后它收集的统计数据与bar的统计数据不同,并且bar的统计数据导致查询计划器设计更好的查询计划,该计划不会超时。

您可以做的一件事是尝试创建类似bar2的东西,并确认其中一个也可以工作,看看您是否可以比较foo,barbar2的查询执行计划。可能foo将不同于barbar2。此外,barbar2应该大致相同。

我希望这对你有帮助。

编辑:正如另一个答案指出的那样——如果上面证明是正确的——你可以执行:VACUUM ANALYZE foo;来刷新统计数据。

最新更新