Domanda

Sto eseguendo la seguente query:

SELECT fat.*   
FROM Table1 fat  
LEFT JOIN modo_captura mc       ON mc.id = fat.modo_captura_id  
INNER JOIN loja lj              ON lj.id = fat.loja_id  
INNER JOIN rede rd              ON rd.id = fat.rede_id  
INNER JOIN bandeira bd          ON bd.id = fat.bandeira_id  
INNER JOIN produto pd           ON pd.id = fat.produto_id  
INNER JOIN loja_extensao le     ON le.id = fat.loja_extensao_id  
INNER JOIN conta ct             ON ct.id = fat.conta_id
INNER JOIN banco bc             ON bc.id = ct.banco_id  
LEFT JOIN conciliacao_vendas cv ON fat.empresa_id = cv.empresa_id AND cv.chavefato = fat.chavefato AND fat.rede_id = cv.rede_id  
WHERE 1 = 1  
AND cv.controle_upload_arquivo_id = 6906  
AND fat.parcela = 1  
ORDER BY fat.data_venda, fat.data_credito limit 20
.

ma molto lentamente.Qui il piano spiegato: http://explain.depesz.com/s/dnxh

È stato utile?

Soluzione

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

Iscriviti sintassi e sequenza di join

In particolare ho fissato il LEFT JOINGcode ingannevole a conciliacao_vendas, che è costretto ad agire come una normale generazioneGoDiceTagCode entro la condizione successiva [INNER] JOIN comunque. Ciò dovrebbe semplificare la pianificazione della query e consentire di eliminare le righe in precedenza nel processo, il che dovrebbe rendere tutto molto più economico. Risposta correlata con spiegazione dettagliata:

WHERE è solo una stenografia sintattica.

Poiché ci sono molte tabelle coinvolte nella query e nell'ordine, le tabelle Joins query riscritte sono ottimale ora, è possibile mettere a punto questo con USING per salvare il sovraccarico di pianificazione ed evitare piani di query inferiori. Corri in un Transazione singola :

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

Maggiori informazioni su questo:

Indice

Aggiungi alcuni indici sulle tabelle di ricerca con lotti o righe (non necessari per solo un paio di dozzine), in particolare (presi dal piano di query):

.

SEQ Scan On Public.Conta Ct ... Rows= 6771
Seq Scan On Public.Loja lj ... Rows= 1568
Seq Scan On Public.Loja_extensao Le ... Righe= 16394

È particolarmente strano, perché quelle colonne assomigliano a colonne chiave primarie e dovrebbero già avere un indice ...

Allora:

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 rendere questo veramente grasso, un indice multicolno sarebbe di ottimo servizio:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top