PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment optimiser les requêtes postgres

Essayez cette version réécrite :

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;

Syntaxe JOIN et séquence de jointures

En particulier, j'ai corrigé le trompeur LEFT JOIN à conciliacao_vendas , qui est forcé d'agir comme un simple [INNER] JOIN par le dernier WHERE état quand même. Cela devrait simplifier la planification des requêtes et permettre d'éliminer les lignes plus tôt dans le processus, ce qui devrait rendre tout beaucoup moins cher. Réponse connexe avec une explication détaillée :

USING n'est qu'un raccourci syntaxique.

Étant donné que de nombreuses tables sont impliquées dans la requête et que l'ordre dans lequel la requête réécrite joint les tables est maintenant optimal, vous pouvez affiner cela avec SET LOCAL join_collapse_limit = 1 pour réduire les frais généraux de planification et éviter les plans de requête inférieurs. Exécuter en une transaction unique :

BEGIN;
SET LOCAL join_collapse_limit = 1;
SELECT ...;  -- read data here
COMMIT;      -- or ROOLBACK;

En savoir plus :

Index

Ajoutez des index sur les tables de recherche avec des lots ou des lignes (pas nécessaire pour seulement quelques dizaines), en particulier (extrait de votre plan de requête) :

C'est particulièrement étrange, car ces colonnes ressemblent à des colonnes de clé primaire et devrait déjà avoir un indice ...

Donc :

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

Pour rendre cela vraiment gras, un index multicolonne rendrait de grands services :

CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);