首页 > 解决方案 > PostgreSQL default_statistics_target 没有改进行估计

问题描述

我正在尝试优化我们对 Postgres 的查询,这有时需要几分钟才能使用巨大的表。开始查看查询计划,并注意到使用EXPLAIN ANALYZE.

这将我引向default_statistics_target控制命令采样的行数ANALYZE以收集查询计划器使用的统计信息的参数。正如少数博客所建议的那样,我尝试通过增加值将其设置为1000并将事件设置为最大允许值10000.

每次ANALYZE运行以确保其统计信息已更新。但令人惊讶的是,这根本没有改善行估计。事实上,它进一步降低了估计值,这似乎很奇怪。

还通过将值减小到 进行测试10。这似乎使计数有所改善。所以我很困惑,如果参数真的做了我认为它做的事情。或者,如果有其他方法可以改进行估计。任何帮助将非常感激。

Postgres 版本:9.6

查询计划:在最后的索引扫描步骤中,估计为 462,但实际为 1.9M。 https://explain.depesz.com/s/GZY

更改后default_statistics_target = 1000,索引扫描步骤中的行是

->  (cost=0.57..120.42 rows=114 width=32) (actual time=248.999..157947.395 rows=1930518 loops=1)

并将其设置为default_statistics_target = 10,计数为:

->  (cost=0.57..2610.79 rows=2527 width=32) (actual time=390.437..62668.837 rows=1930518 loops=1)

正在考虑的 PS 表有超过 100M 行。

标签: postgresqlperformancequery-optimization

解决方案


这看起来像一个相关性问题。规划器假设 project_id、event_name_id 和“timestamp”的条件是独立的,因此会乘以它们的估计选择性。如果它们不是独立的,那么再多的传统统计数据也无济于事。也许您需要扩展统计信息

此外,在制定计划时,它甚至不知道 event_name_id 将与哪个值进行比较,因为 $0 直到运行时才确定,因此它不能为此使用特定于值的统计信息。您可以手动执行子查询,然后将结果值硬编码到查询中的该位置,因此规划器在规划时知道该值是什么。


推荐阅读