我正在尝试优化在 PostgreSQL 15.4 中连接两个大表(40MM+ 行)的查询。
SELECT files.id, ARRAY_AGG(b.status)
FROM files
LEFT OUTER JOIN processing_tasks b
ON (files.id = b.file_id AND b.job_id = 113)
WHERE files.round_id = 591
GROUP BY files.id;
explain (analyze)
完全相同的查询的两个计划位于:
https://explain.depesz.com/s/cUXB需要 87 秒,使用并行 Seq 扫描
processing_tasks.job_id
(默认计划)https://explain.depesz.com/s/j39G需要 4 秒,使用位图索引扫描
processing_tasks.job_id
(当 时set local enable_seqscan = OFF
)
在 中files
,908,275 / 39,000,105 (2.3%) 个元组有round_id=591
; 它是静态的。
在 中processing_tasks
,4,026,364 / 60,780,802 (6.6%) 个元组有job_id=113
,并且随着行的插入,这个值将变得越来越常见,可能达到表的 15%。
这些链接上的“注释”选项卡包括表和索引定义,并显示数据pg_stats
包括这些最常见的值。
我对以下几个可能的目标中的任何一个都感到满意:
使用索引扫描时花费的 3-4 秒是可以接受的,如果这是我能做的最好的事情,那么
enable_seqscan
即使在生产中我也应该继续覆盖吗?(我猜是在交易中)但我宁愿进一步减少 3-4 秒,减少到 2 秒以下,并且随着
processing_tasks
时间的增长而保持不变。