我正在运行以下查询:

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

但非常缓慢。这里是解释计划: http://explain.depesz.com/s/DnXH

有帮助吗?

解决方案

尝试这个重写版本:

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 语法和连接顺序

特别是我修复了 误导性的 LEFT JOINconciliacao_vendas, ,它被迫充当普通 [INNER] JOIN 由后来的 WHERE 无论如何条件。这应该会简化查询规划,并允许在过程的早期消除行,这将使一切变得更便宜。相关答案及详细解释:

USING 只是语法简写。

由于查询涉及很多表,并且重写的查询连接表的顺序现在是最佳的,因此您可以使用以下命令对此进行微调 SET LOCAL join_collapse_limit = 1 以节省计划开销并避免较差的查询计划。运行在一个 单笔交易:

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

更多相关内容:

指数

在包含大量或行的查找表上添加一些索引(对于几十行来说不需要),特别是(取自查询计划):

对 public.conta ct 进行顺序扫描 ... 行=6771
对 public.loja lj 进行序列扫描 ... 行=1568
对 public.loja_extensao 文件进行 Seq 扫描 ... 行=16394

这特别奇怪,因为这些列看起来像 主键列 并且应该已经 一个索引...

所以:

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

为了让这个真的很胖, 多列索引 会有很大的服务:

CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top