PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

So optimieren Sie Abfrage-Postgres

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:

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);