我正在使用AWS RDS Postgres v13.7
我有一个表foo,大约有100万行。我在CTE中的2列上运行了一个select distinct查询,之后运行了一个self join,最后运行了一个select count(*)。
我使用create table bar as (select * from foo)
克隆。我在这个表上运行相同的查询。
使用foo的查询挂起并且永远不会完成。使用bar的查询在10秒内完成。我并排运行/启动它们,并尝试在另一个之前运行一个,所以它不是资源或查询顺序问题;foo永远不会完成,bar总是在几秒钟内完成。下午有一段时间foo查询也会很快完成,所以可能有一个时间问题。
实际上,相同的数据和查询具有不同的结果。
我已经做了一个真空。解释2表和查询是相同的。
当我尝试分解CTE时,foo或bar上的select distinct执行相同的操作,正如预期的那样。挂起的是foo上的self连接。
我已经读过the post "Identical tables, identical query, completely different execution times"和Exactly same query and plan but different duration and total reads. I Know parameter sniffing but,我不相信它们适用于我的情况
我的期望是foo查询应该和bar查询一样快,或者它们的行为方式相同
2条答案
按热度按时间jvidinwx1#
Postgres设计的查询执行计划依赖于查询语义、可用索引、服务器配置等,但它也依赖于postgres收集的有关数据的表统计信息(请参阅:最后,基于启发式设计查询计划。
我猜对于你的情况,可能是
foo
可能已经存在了更长的时间,然后它收集的统计数据与bar
不同,bar
统计数据导致查询规划器设计一个更好的查询计划,不会超时。你可以做的一件事是尝试创建类似
bar2
的东西,并确认一个也可以工作,看看你是否可以比较foo
,bar
和bar2
的查询执行计划。很可能foo与bar
或bar2
不同。此外,bar
和bar2
应该大致相同。我希望这能帮上一点忙。
cyvaqqii2#
在PostgreSQL中,VACUUM回收死元组占用的存储,ANALYZE更新统计信息,或者使用VACUUM ANALYZE回收存储和更新表统计信息。
例如: