特定 PostgreSQL 客户端/版本中的慢查询
Posted
技术标签:
【中文标题】特定 PostgreSQL 客户端/版本中的慢查询【英文标题】:Slow queries in specific PostgreSQL client/version 【发布时间】:2021-03-17 20:17:05 【问题描述】:我有一个返回 0 行的查询,但最终 - 在一台特定的机器上 - 大约需要 10 秒才能完成。在我使用相同数据库(尽管 postgres 版本不同)测试的所有其他机器上,查询几乎是即时的。
此外,我通过对查询执行“解释(分析)”得到的结果在“快速”机器中是相同的,但在有问题的机器中有点不同,它似乎从不执行并行 seq扫描,所有其他机器都会这样做,即使每台机器上的并行工作器配置都相同。结果(所有相同的数据库,PC#1 是有问题的):
PC#1, PostgreSQL 11.5
Seq Scan on cc_parc (cost=0.00..1175721.63 rows=58 width=853) (actual time=9537.152..9537.152 rows=0 loops=1)
Filter: ((class = 'db1.C_Parcela'::text) AND (fact = 221327))
Rows Removed by Filter: 217422
Buffers: shared hit=8034 read=1163008
Planning Time: 0.448 ms
Execution Time: 9537.602 ms
PC#2, PostgreSQL 12.1
Gather (cost=1000.00..11684.49 rows=6 width=377) (actual time=136.784..139.779 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
Buffers: shared hit=344 read=8981
-> Parallel Seq Scan on cc_parc (cost=0.00..10683.89 rows=2 width=377) (actual time=30.167..30.167 rows=0 loops=3)
Filter: ((class = 'db1.C_Parcela'::text) AND (fact = 221327))
Rows Removed by Filter: 72474
Buffers: shared hit=344 read=8981
Planning Time: 1.945 ms
Execution Time: 139.860 ms
PC#3, PostgreSQL 13.2
Gather (cost=1000.00..11684.39 rows=5 width=1495) (actual time=70.610..88.546 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
Buffers: shared hit=212 read=9113
-> Parallel Seq Scan on cc_parc (cost=0.00..10683.89 rows=2 width=1495) (actual time=43.353..43.353 rows=0 loops=3) Filter: ((class = 'db1.C_Parcela'::text) AND (fact = 221327))
Rows Removed by Filter: 72474
Buffers: shared hit=212 read=9113
Planning:
Buffers: shared hit=311 read=6
Planning Time: 1.047 ms
Execution Time: 88.604 ms
PC#4, PostgreSQL 10.5
Gather (cost=1000.00..11685.63 rows=6 width=377) (actual time=98.253..121.924 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
Buffers: shared hit=2 read=9324
-> Parallel Seq Scan on cc_parc (cost=0.00..10685.03 rows=2 width=377) (actual time=53.534..53.535 rows=0 loops=3)
Filter: ((class = 'db1.C_Parcela'::text) AND (fact = 221327))
Rows Removed by Filter: 72474
Buffers: shared hit=2 read=9324
Planning time: 7.315 ms
Execution time: 122.090 ms
另外过滤的行数不同,具体查询(select * from cc_parc where class='db1.C_Parcela' and fact=221327;
) 返回 0 行,其计数值为 217422,但在不同的机器中过滤器的行数不同,
PC#1 - 过滤器删除的行数:217422
所有其他 PC - 过滤器删除的行数:72474
我也尝试在同一台机器上运行所有相同的测试,但使用 PostgreSQL 12 并且情况已经解决,这些值又是预期的值:
PC#1, PostgreSQL 12.2
Gather (cost=1000.00..11684.59 rows=7 width=377) (actual time=94.210..99.924 rows=0 loops=1)
Workers Planned: 2
Workers Launched: 2
Buffers: shared hit=370 read=8955
-> Parallel Seq Scan on cc_parc (cost=0.00..10683.89 rows=3 width=377) (actual time=51.816..51.816 rows=0 loops=3)
Filter: ((class = 'db1.C_Parcela'::text) AND (fact = 221327))
Rows Removed by Filter: 72474
Buffers: shared hit=370 read=8955
Planning Time: 4.815 ms
Execution Time: 100.059 ms
我可以安全地假设 PostgreSQL 11 版本中存在某种错误导致此问题,还是有人有其他想法?
【问题讨论】:
可能类似于this @a_horse_with_no_name 有趣的文章,但可能不是问题,因为对数据库的访问都不是从您可以限制最大行数的地方完成的——所有这些都是从命令行完成的。计划中的工人甚至没有出现。当我将 max_worker_processes 和相关的 worker 参数更改为愚蠢的数量(例如 99)时,我设法让 1 个 Worker 出现,但只有 1 个出现,并且查询时间没有差异。 【参考方案1】:我注意到,在同一 psql 版本中进行转储和恢复后,问题自行解决了。
在分析 select * from pgstattuple('public.cc_parc');
的输出并比较“错误”数据库与正常运行的数据库中的结果后,我注意到错误数据库中的 table_length 大了 125 倍......这当然不应该是事实。
在表上运行 VACUUM FULL
后,table_length 恢复到正确值,完全解决了慢问题。
运行完全真空似乎并不可取,因此我将尝试找出使数据库如此臃肿的原因。显然here 中的大多数建议似乎都是合适的
【讨论】:
以上是关于特定 PostgreSQL 客户端/版本中的慢查询的主要内容,如果未能解决你的问题,请参考以下文章