Hãy thử phiên bản viết lại này:
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;
Cú pháp JOIN và trình tự các phép nối
Đặc biệt, tôi đã sửa lỗi LEFT JOIN
gây hiểu lầm tới conciliacao_vendas
, buộc phải hoạt động như một [INNER] JOIN
đơn giản bởi WHERE
sau điều kiện nào cũng được. Điều này sẽ đơn giản hóa việc lập kế hoạch truy vấn và cho phép loại bỏ các hàng sớm hơn trong quá trình, điều này sẽ làm cho mọi thứ rẻ hơn rất nhiều. Câu trả lời liên quan với giải thích chi tiết:
USING
chỉ là một cách viết tắt cú pháp.
Vì có nhiều bảng tham gia vào truy vấn và thứ tự truy vấn được viết lại kết hợp các bảng bây giờ là tối ưu, bạn có thể tinh chỉnh điều này với SET LOCAL join_collapse_limit = 1
để tiết kiệm chi phí lập kế hoạch và tránh các kế hoạch truy vấn kém hơn. Chạy trong một giao dịch duy nhất :
BEGIN;
SET LOCAL join_collapse_limit = 1;
SELECT ...; -- read data here
COMMIT; -- or ROOLBACK;
Tìm hiểu thêm về điều đó:
- Truy vấn mẫu để hiển thị lỗi ước tính Cardinality trong PostgreSQL
- Sách hướng dẫn chi tiết về Kiểm soát Công cụ lập kế hoạch với Nội dung khiêu dâm THAM GIA các điều khoản
Chỉ mục
Thêm một số chỉ mục trên các bảng tra cứu có nhiều hoặc nhiều hàng (không cần thiết cho chỉ vài chục), cụ thể là (lấy từ kế hoạch truy vấn của bạn):
Điều đó đặc biệt kỳ lạ, bởi vì những cột đó trông giống như cột khóa chính và lẽ ra đã có một chỉ mục ...
Vì vậy:
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);
Để làm cho điều này thực sự quan trọng, hãy chỉ mục nhiều cột sẽ có dịch vụ tuyệt vời:
CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);