In genere, il pianificatore di query di Postgres fa viste "inline" per ottimizzare l'intera query. Per documentazione:
Ma non credo che Postgres sia abbastanza intelligente per concludere che può raggiungere lo stesso risultato dalla tabella di base senza esplodere le righe.
Puoi provare questa query alternativa con un LATERAL
giuntura. È più pulito:
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;
Inoltre chiarisce che uno dei (end_day
, start_day
) è ridondante.
Usando LEFT JOIN
perché ciò potrebbe consentire al pianificatore di query di ignorare il join dalla tua query:
SELECT DISTINCT type FROM v_mt_count_by_day;
Altrimenti (con un CROSS JOIN
o INNER JOIN
) deve valuta il join per vedere se le righe della prima tabella vengono eliminate.
A proposito, è:
SELECT DISTINCT type ...
non:
SELECT DISTINCT(type) ...
Nota che questo restituisce una date
invece del timestamp nell'originale. Più facile, e immagino sia quello che vuoi comunque?
Richiede Postgres 9.3+ Dettagli:
ROWS FROM
in Postgres 9.4+
Per esplodere entrambe le colonne in parallelo in sicurezza :
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;
Il vantaggio principale:questo non deraglia in un prodotto cartesiano se i due SRF non restituiscono lo stesso numero di righe. Invece, i valori NULL verrebbero riempiti.
Ancora una volta, non posso dire se questo aiuterebbe il pianificatore di query con un piano più veloce per DISTINCT type
senza test.