Generelt gør det Postgres-forespørgselsplanlæggeren "inline" visninger for at optimere hele forespørgslen. Pr. dokumentation:
Men jeg synes ikke, at Postgres er smart nok at konkludere, at den kan nå det samme resultat fra basistabellen uden at eksplodere rækker.
Du kan prøve denne alternative forespørgsel med en LATERAL
tilslutte. Det er renere:
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;
Det gør det også klart, at en af (end_day
, startdag
) er overflødig.
Bruger LEFT JOIN
fordi det kan tillade forespørgselsplanlæggeren at ignorere joinforbindelsen fra din forespørgsel:
SELECT DISTINCT type FROM v_mt_count_by_day;
Ellers (med en CROSS JOIN
eller INNER JOIN
) det skal evaluer joinforbindelsen for at se, om rækker fra den første tabel er elimineret.
BTW, det er:
SELECT DISTINCT type ...
ikke:
SELECT DISTINCT(type) ...
Bemærk, at dette returnerer en dato
i stedet for tidsstemplet i din original. Easer, og det er vel alligevel det, du vil have?
Kræver Postgres 9.3+ Detaljer:
RÆKKER FRA
i Postgres 9.4+
For at eksplodere begge kolonner parallelt sikkert :
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;
Den største fordel:Dette ville ikke afspore til et kartesisk produkt, hvis de to SRF ikke returnerer det samme antal rækker. I stedet vil NULL-værdier blive udfyldt.
Igen, jeg kan ikke sige, om dette ville hjælpe forespørgselsplanlæggeren med en hurtigere plan for DISTINCT type
uden at teste.