Experimente esta versão reescrita:
SELECT fat.*
FROM Table1 fat
JOIN conciliacao_vendas cv USING (empresa_id, chavefato, rede_id)
JOIN loja lj ON lj.id = fat.loja_id
JOIN rede rd ON rd.id = fat.rede_id
JOIN bandeira bd ON bd.id = fat.bandeira_id
JOIN produto pd ON pd.id = fat.produto_id
JOIN loja_extensao le ON le.id = fat.loja_extensao_id
JOIN conta ct ON ct.id = fat.conta_id
JOIN banco bc ON bc.id = ct.banco_id
LEFT JOIN modo_captura mc ON mc.id = fat.modo_captura_id
WHERE cv.controle_upload_arquivo_id = 6906
AND fat.parcela = 1
ORDER BY fat.data_venda, fat.data_credito
LIMIT 20;
Sintaxe JOIN e sequência de junções
Em particular, consertei o enganoso
LEFT JOIN
para conciliacao_vendas
, que é forçado a agir como um simples [INNER] JOIN
pelo posterior WHERE
condição de qualquer maneira. Isso deve simplificar o planejamento de consultas e permitir a eliminação de linhas no início do processo, o que deve tornar tudo muito mais barato. Resposta relacionada com explicação detalhada:USING
é apenas uma abreviação sintática. Como há muitas tabelas envolvidas na consulta e a ordem em que a consulta reescrita une as tabelas é ideal agora, você pode ajustar isso com
SET LOCAL join_collapse_limit = 1
para economizar a sobrecarga de planejamento e evitar planos de consulta inferiores. Executar em uma transação única :BEGIN;
SET LOCAL join_collapse_limit = 1;
SELECT ...; -- read data here
COMMIT; -- or ROOLBACK;
Mais sobre isso:
- Consulta de amostra para mostrar erro de estimativa de cardinalidade no PostgreSQL
- O bom manual sobre Controlar o planejador com explícito Cláusulas JOIN
Índice
Adicione alguns índices em tabelas de pesquisa com lotes ou linhas (não é necessário apenas algumas dezenas), em particular (retirados do seu plano de consulta):
Isso é particularmente estranho, porque essas colunas se parecem com colunas de chave primária e já deve ter Um índice ...
Então:
CREATE INDEX conta_pkey_idx ON public.conta (id);
CREATE INDEX loja_pkey_idx ON public.loja (id);
CREATE INDEX loja_extensao_pkey_idx ON public.loja_extensao (id);
Para tornar isso realmente gordo, um índice de várias colunas seria de grande utilidade:
CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);