Over het algemeen doet de Postgres-queryplanner dat wel "inline" weergaven om de hele zoekopdracht te optimaliseren. Per documentatie:
Maar ik denk niet dat Postgres slim genoeg is om te concluderen dat het hetzelfde resultaat van de basistabel kan bereiken zonder rijen te laten exploderen.
U kunt deze alternatieve zoekopdracht proberen met een LATERAL
meedoen. Het is schoner:
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;
Het maakt ook duidelijk dat een van (end_day
, start_day
) is overbodig.
LEFT JOIN
gebruiken omdat de queryplanner daardoor de join van uw query kan negeren:
SELECT DISTINCT type FROM v_mt_count_by_day;
Anders (met een CROSS JOIN
of INNER JOIN
) het moet evalueer de join om te zien of rijen uit de eerste tabel zijn geëlimineerd.
Tussen haakjes, het is:
SELECT DISTINCT type ...
niet:
SELECT DISTINCT(type) ...
Merk op dat dit een date
retourneert in plaats van de tijdstempel in uw origineel. Makkelijker, en ik denk dat het toch is wat je wilt?
Vereist Postgres 9.3+ Details:
ROWS FROM
in Postgres 9.4+
Beide kolommen veilig parallel laten exploderen :
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;
Het belangrijkste voordeel:dit zou niet ontsporen tot een cartesiaans product als de twee SRF niet hetzelfde aantal rijen retourneren. In plaats daarvan zouden NULL-waarden worden opgevuld.
Nogmaals, ik kan niet zeggen of dit de queryplanner zou helpen met een sneller plan voor DISTINCT type
zonder testen.