Estou tentando otimizar uma consulta que une duas tabelas grandes (mais de 40 milhões de linhas) no PostgreSQL 15.4.
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;
Dois explain (analyze)
planos para exatamente a mesma consulta estão em:
https://explain.depesz.com/s/cUXB leva 87 segundos, usa Parallel Seq Scan ativado
processing_tasks.job_id
(plano padrão)https://explain.depesz.com/s/j39G leva 4 segundos, usa varredura de índice de bitmap ativada
processing_tasks.job_id
(quandoset local enable_seqscan = OFF
)
Em files
, 908.275/39.000.105 (2,3%) tuplas possuem round_id=591
; é estático.
Em processing_tasks
, 4.026.364/60.780.802 (6,6%) tuplas possuem job_id=113
, e esse valor vai se tornar cada vez mais comum à medida que as linhas são inseridas, talvez chegando a 15% da tabela.
A guia "Comentários" nesses links inclui definições de tabela e índice e mostra que os pg_stats
dados incluem esses valores mais comuns.
Eu ficaria feliz com um dos dois objetivos possíveis:
Os 3 a 4 segundos necessários ao usar o Index Scan são aceitáveis e, se isso for o melhor que posso fazer, devo continuar a substituir,
enable_seqscan
mesmo na produção? (dentro de uma transação, eu acho)Mas prefiro reduzir ainda mais esses 3-4 segundos, para menos de 2 segundos, e mantê-los assim à medida que
processing_tasks
cresce.