Postgres 不同的查询计划 Prod/QA
Posted
技术标签:
【中文标题】Postgres 不同的查询计划 Prod/QA【英文标题】:Postgres Differing Query Plans Prod/QA 【发布时间】:2018-05-22 00:19:10 【问题描述】:我有两台数据库服务器,它们都处于“测试”模式,其中一台预计会升级到生产服务器。因此,规格和一些配置有所不同,但我们发现动力不足的服务器会产生更好的查询计划,因此查询速度会更快。
统计数据:
两个系统的数据大致相同,数量如下:
Size | Part
--------------------
1.47 TB | Entire DB
871 GB | Tables
635 GB | Indexes
更大的数据库服务器具有以下规格:
内存:500 GB
CPU:16 核 2.0 GHz 英特尔
使用固态硬盘
Postgres 10.0
Memlock 设置为专门为 Postgres 保留 485 GB
Postgres 设置:
shared_buffers
:125 GB
work_mem
:36 MB
effective_cache_size
:300 GB
random_page_cost
: 1
default_statistics_target
: 1000
查询计划:https://explain.depesz.com/s/9Ww6
较小的服务器具有以下统计信息:
内存:281 GB
CPU:4 核 2.0 GHz 英特尔
使用固态硬盘
Postgres 10.0
Memlock 设置为专门为 Postgres 保留 240 GB
Postgres 设置:
shared_buffers
: 50 GB
work_mem
:25.6 MB
effective_cache_size
:150 GB
random_page_cost
: 4
default_statistics_target
: 100
查询计划:https://explain.depesz.com/s/4WUH
我们尝试切换 random_page_cost、默认统计信息(随后是分析)和工作内存以相互匹配。在查询中的所有表上运行vacuum full
后,最大的收获是。
工作负载:这台机器是一个只读副本,用于将数据的文件提取为XML文件等。因此它接收复制的数据并且具有相当重的读取负载。
问题:我应该寻找什么来使这个查询在运行速度较慢的大型服务器上更高效?理想情况下,此查询比在较小的服务器上运行得快得多。看来,当我们进行扩展时,我们未能正确设置设置以利用我们的硬件。一定有什么我忽略了。
编辑:我提出了非混淆计划。我还尝试将统计数据从 1000 增加到 3000,但这对计划没有帮助。更改 random_page_cost 以在服务器之间匹配也是如此。
【问题讨论】:
【参考方案1】:两台机器上的PostgreSQL配置差异很大,所以查询计划不同也就不足为奇了。特别是random_page_cost
影响很大。
您绝对应该使用不同的shared_buffers
设置对您的工作负载进行基准测试:您的设置可能太高了(通常,8GB 比较合适)。
但我认为两个你的查询计划都很糟糕,而且你的问题出在不同的地方。
优化器错误地估计了从showtimes.mappable_program
上的索引扫描返回的行数,这种错误估计会导致更严重的错误估计和错误的计划选择。
尝试增加列上统计信息的密度:
ALTER TABLE showtimes.mappable_program ALTER mapping_scheme_id
SET STATISTICS 1000;
然后ANALYZE
桌子。
如果这不起作用,请通过替换来修改查询
WHERE COALESCE(mp2.ignore::integer, 0) = 0
与
WHERE mp2.ignore = '0' OR mp2.ignore IS NULL
这可能有助于优化器更好地估计条件。
【讨论】:
啊,是的,random_io_cost 应该是 random_page_cost。但是,我在测试期间确实更改了值以匹配每台服务器,并且计划没有改变。此外,我们在每台服务器上运行相同的查询。你是对的,我混淆了查询。今天我会试试你的建议。谢谢 我已经发布了未混淆的计划。我尝试了您的建议,但没有提高性能。还有其他建议吗? 创建索引并运行ANALYZE
后我可以看到计划吗?
这是在创建索引并运行新的真空/分析之后:explain.depesz.com/s/khYZ
我认为你可以删除索引。我已经修改了我的答案,试试这些想法。以上是关于Postgres 不同的查询计划 Prod/QA的主要内容,如果未能解决你的问题,请参考以下文章