Versuchen Sie diese umgeschriebene Version:
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;
JOIN-Syntax und Join-Reihenfolge
Insbesondere habe ich den irreführenden LEFT JOIN
korrigiert zu conciliacao_vendas
, der gezwungen wird, als einfacher [INNER] JOIN
zu fungieren durch das spätere WHERE
Zustand sowieso. Dies sollte die Abfrageplanung vereinfachen und es ermöglichen, Zeilen früher im Prozess zu eliminieren, was alles viel billiger machen sollte. Verwandte Antwort mit ausführlicher Erklärung:
USING
ist nur eine syntaktische Abkürzung.
Da viele Tabellen an der Abfrage beteiligt sind und die Reihenfolge, in der die umgeschriebene Abfrage Tabellen verknüpft, jetzt optimal ist, können Sie dies mit SET LOCAL join_collapse_limit = 1
feinabstimmen um Planungsaufwand zu sparen und minderwertige Abfragepläne zu vermeiden. In einer einzelnen Transaktion ausführen :
BEGIN;
SET LOCAL join_collapse_limit = 1;
SELECT ...; -- read data here
COMMIT; -- or ROOLBACK;
Mehr dazu:
- Beispielabfrage zum Anzeigen des Kardinalitätsschätzungsfehlers in PostgreSQL
- Das feine Handbuch zur Steuerung des Planers mit Explicit JOIN-Klauseln
Index
Fügen Sie einige Indizes zu Nachschlagetabellen mit Losen oder Zeilen hinzu (nicht notwendig für nur ein paar Dutzend), insbesondere (aus Ihrem Abfrageplan entnommen):
Das ist besonders seltsam, weil diese Spalten wie Primärschlüsselspalten aussehen und sollte es bereits haben ein Index ...
Also:
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);
Um das richtig fett zu machen, ein mehrspaltiger Index wäre von großem Nutzen:
CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);