Obecně platí, že plánovač dotazů Postgres dělá „inline“ pohledy pro optimalizaci celého dotazu. Podle dokumentace:
Ale nemyslím si, že Postgres je dostatečně chytrý k závěru, že může dosáhnout stejného výsledku ze základní tabulky bez rozkládání řádků.
Tento alternativní dotaz můžete zkusit pomocí LATERAL
připojit. Je to čistší:
CREATE OR REPLACE VIEW runinfo.v_mt_count_by_day AS
SELECT m.run_id, m.type, m.brand
, m.start_day + c.rn - 1 AS row_date
, c.row_count
FROM runinfo.mt_count_by_day m
LEFT JOIN LATERAL unnest(m.counts) WITH ORDINALITY c(row_count, rn) ON true;
Také je jasné, že jeden z (end_day
, start_day
) je nadbytečné.
Pomocí LEFT JOIN
protože to může umožnit plánovači dotazů ignorovat spojení z vašeho dotazu:
SELECT DISTINCT type FROM v_mt_count_by_day;
Jinak (s CROSS JOIN
nebo INNER JOIN
) musí vyhodnoťte spojení, abyste viděli, zda jsou odstraněny řádky z první tabulky.
BTW, je to:
SELECT DISTINCT type ...
ne:
SELECT DISTINCT(type) ...
Všimněte si, že to vrátí date
místo časového razítka ve vašem originále. Easer, a myslím, že je to to, co stejně chcete?
Vyžaduje Postgres 9.3+ Podrobnosti:
ROWS FROM
v Postgres 9.4+
Chcete-li rozložit oba sloupce paralelně bezpečně :
CREATE OR REPLACE VIEW runinfo.v_mt_count_by_day AS
SELECT m.run_id, m.type, m.brand
t.row_date::date, t.row_count
FROM runinfo.mt_count_by_day m
LEFT JOIN LATERAL ROWS FROM (
unnest(m.counts)
, generate_series(m.start_day, m.end_day, interval '1d')
) t(row_count, row_date) ON true;
Hlavní výhoda:Toto by nevykolejilo do kartézského součinu, pokud dva SRF nevracejí stejný počet řádků. Místo toho by byly doplněny hodnoty NULL.
Opět nemohu říci, zda by to pomohlo plánovači dotazů s rychlejším plánem pro DISTINCT type
bez testování.