Wypróbuj tę przepisaną wersję:
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;
Składnia JOIN i sekwencja złączeń
W szczególności naprawiłem mylące LEFT JOIN
do conciliacao_vendas
, który jest zmuszony do działania jako zwykły [INNER] JOIN
przez późniejsze WHERE
stan tak czy inaczej. Powinno to uprościć planowanie zapytań i pozwolić na eliminację wierszy na wcześniejszym etapie procesu, co powinno sprawić, że wszystko będzie dużo tańsze. Powiązana odpowiedź ze szczegółowym wyjaśnieniem:
USING
to tylko skrót składniowy.
Ponieważ w zapytaniu zaangażowanych jest wiele tabel, a kolejność, w jakiej przepisane zapytanie łączy tabele, jest teraz optymalna, można to dostroić za pomocą SET LOCAL join_collapse_limit = 1
aby zaoszczędzić na kosztach planowania i uniknąć gorszych planów zapytań. Uruchom w pojedynczej transakcji :
BEGIN;
SET LOCAL join_collapse_limit = 1;
SELECT ...; -- read data here
COMMIT; -- or ROOLBACK;
Więcej na ten temat:
- Przykładowe zapytanie pokazujące błąd szacowania kardynalności w PostgreSQL
- Doskonały podręcznik Kontroli terminarza za pomocą Klauzule JOIN
Indeks
Dodaj indeksy do tabel przeglądowych z partiami lub wierszami (nie jest to konieczne tylko dla kilkudziesięciu), w szczególności (pobrane z planu zapytań):
To szczególnie dziwne, ponieważ te kolumny wyglądają jak kolumny klucza głównego i powinien już mieć indeks ...
A więc:
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);
Aby było naprawdę tłuste, indeks wielokolumnowy byłoby bardzo pomocne:
CREATE INDEX foo ON Table1 (parcela, data_venda, data_credito);