Prova questa versione riscritta:
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;
Sintassi JOIN e sequenza di join
In particolare ho corretto il LEFT JOIN
ingannevole a conciliacao_vendas
, che è costretto ad agire come un semplice [INNER] JOIN
dal successivo WHERE
condizione comunque. Ciò dovrebbe semplificare la pianificazione delle query e consentire di eliminare le righe in precedenza nel processo, il che dovrebbe rendere tutto molto più economico. Risposta correlata con spiegazione dettagliata:
USING
è solo una scorciatoia sintattica.
Poiché ci sono molte tabelle coinvolte nella query e l'ordine in cui la query riscritta unisce le tabelle è ora ottimale, puoi perfezionarlo con SET LOCAL join_collapse_limit = 1
per risparmiare il sovraccarico di pianificazione ed evitare piani di query inferiori. Esegui in una singola transazione :
BEGIN;
SET LOCAL join_collapse_limit = 1;
SELECT ...; -- read data here
COMMIT; -- or ROOLBACK;
Maggiori informazioni:
- Esempio di query per mostrare l'errore di stima della cardinalità in PostgreSQL
- Il bel manuale su Controllare il Planner con Explicit Clausole JOIN
Indice
Aggiungi alcuni indici su tabelle di ricerca con lotti o righe (non necessari solo per un paio di dozzine), in particolare (presi dal tuo piano di query):
È particolarmente strano, perché quelle colonne sembrano colonne chiave primarie e dovrebbe già avere un indice...
Quindi:
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);
Per renderlo davvero grasso, un indice a più colonne sarebbe di grande aiuto:
CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);