如何解决Postgres 不使用带聚合的覆盖索引
引擎版本:12.4
Postgres 没有使用仅索引扫描,然后我运行了vacuum analysisverbose table_name。之后它开始使用仅索引扫描。早些时候,当我在没有真空的情况下运行分析详细 table_name 时,没有使用仅扫描时间索引。
所以这意味着使用仅索引计划非常依赖于vacuum。有没有办法消除这种依赖性,或者我们应该经常配置真空吗?频率如每天。
我们的目标是减少 cpu 使用率。全天机器 cpu 使用率是 10%-15%,但是当这个查询运行时,cpu 变得非常高(这个查询在多个线程中同时运行,具有差异值)
EXPLAIN ANALYZE SELECT COALESCE(requested_debit,0) AS requestedDebit,COALESCE(requested_credit,0) AS requestedCredit
FROM (SELECT COALESCE(Sum(le.credit),0) AS requested_credit,COALESCE(Sum(le.debit),0) AS requested_debit
FROM ledger_entries le
WHERE le.accounting_entity_id = 1
AND le.general_ledger_id = 503
AND le.post_date BETWEEN '2020-09-10' AND '2020-11-30') AS requested_le;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Subquery Scan on requested_le (cost=66602.65..66602.67 rows=1 width=64) (actual time=81.263..81.352 rows=1 loops=1)
-> Finalize Aggregate (cost=66602.65..66602.66 rows=1 width=64) (actual time=81.261..81.348 rows=1 loops=1)
-> Gather (cost=66602.41..66602.62 rows=2 width=64) (actual time=79.485..81.331 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=65602.41..65602.42 rows=1 width=64) (actual time=74.293..74.294 rows=1 loops=3)
-> Parallel Index Only Scan using post_date_gl_id_accounting_entity_id_include_idx on ledger_entries le (cost=0.56..65203.73 rows=79735 width=8) (actual time=47.874..74.212 rows=197 loops=3)
Index Cond: ((post_date >= '2020-09-10'::date) AND (post_date <= '2020-11-30'::date) AND (general_ledger_id = 503) AND (accounting_entity_id = 1))
Heap Fetches: 0
Planning Time: 0.211 ms
Execution Time: 81.395 ms
(11 rows)
解决方法
PostgreSQL 中的 VACUUM
和仅索引扫描之间有很强的联系:如果包含行的块被标记为所有,仅索引扫描只能跳过获取表行(以检查可见性) - 在可见性地图中可见。可见性地图由 VACUUM
更新。
是的,您必须经常 VACUUM
才能获得高效的仅索引扫描。
通常情况下,无需安排手动 VACUUM
,您只需
ALTER TABLE mytab SET (autovacuum_vacuum_scale_factor = 0.01);
(或类似的值)并让 autovacuum 完成这项工作。
唯一有问题的情况是仅插入表,因为对于它们来说,v13 以下的 PostgreSQL 版本不会触发 autovacuum。在 v13 中,您可以简单地更改 autovacuum_vacuum_insert_scale_factor
,而在旧版本中,您必须将该表的 autovacuum_freeze_max_age
设置为较低的值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。