Pergunta

Estou executando a seguinte consulta:

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

Mas muito lentamente.Aqui a Explicar o plano: http://explain.depesz.com/s/DnXH

Foi útil?

Solução

Experimente esta versão reescrita:

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;

JUNTE-se a sintaxe e a seqüência de associações

Em particular, eu fixo o enganosa LEFT JOIN para conciliacao_vendas, que é forçado a agir como um simples [INNER] JOIN pela tarde WHERE condição de qualquer maneira.Isso deve simplificar a consulta de planeamento e permitem eliminar linhas anteriores no processo, o que deve fazer tudo muito mais barato.Relacionados resposta com explicação detalhada:

USING é apenas uma sintaxe abreviada.

Uma vez que existem muitas tabelas envolvidas na consulta e a ordem em que a reescrita de consulta junções de tabelas é o ideal agora, você pode ajustar esta com SET LOCAL join_collapse_limit = 1 para guardar o planejamento de sobrecarga e evitar inferior planos de consulta.Executar em um única transação:

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

Mais sobre isso:

Índice de

Adicionar alguns índices em tabelas de pesquisa com muita ou linhas (não necessário para apenas um par de dezenas), em particular (tomadas a partir do seu plano de consulta):

Seq Scan em público.conta ct ... linhas=6771
Seq Scan em público.loja lj ... linhas=1568
Seq Scan em público.loja_extensao le ... linhas=16394

Isso é particularmente estranho, porque essas colunas parecer colunas de chave primária e já deve tem um índice ...

Assim:

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

Para tornar esta muito gorda, um índice com várias colunas seria de grande serviço:

CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top