Im Allgemeinen macht es der Postgres-Abfrageplaner "Inline"-Ansichten, um die gesamte Abfrage zu optimieren. Pro Dokumentation:
Aber ich halte Postgres nicht für intelligent genug daraus zu schließen, dass es dasselbe Ergebnis aus der Basistabelle erreichen kann, ohne Zeilen zu explodieren.
Sie können diese alternative Abfrage mit einem LATERAL
versuchen beitreten. Es ist sauberer:
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;
Es macht auch deutlich, dass einer von (end_day
, start_day
) ist überflüssig.
Verwenden von LEFT JOIN
da dies dem Abfrageplaner ermöglichen könnte, den Join aus Ihrer Abfrage zu ignorieren:
SELECT DISTINCT type FROM v_mt_count_by_day;
Sonst (mit einem CROSS JOIN
oder INNER JOIN
) es muss den Join auswerten, um zu sehen, ob Zeilen aus der ersten Tabelle eliminiert werden.
Übrigens, es ist:
SELECT DISTINCT type ...
nicht:
SELECT DISTINCT(type) ...
Beachten Sie, dass dies ein date
zurückgibt anstelle des Zeitstempels in Ihrem Original. Einfacher, und ich denke, es ist sowieso das, was Sie wollen?
Erfordert Postgres 9.3+ Einzelheiten:
ROWS FROM
in Postgres 9.4+
Beide Säulen parallel sicher explodieren zu lassen :
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;
Der Hauptvorteil:Dies würde nicht zu einem kartesischen Produkt entgleisen, wenn die beiden SRF nicht die gleiche Anzahl von Zeilen zurückgeben. Stattdessen würden NULL-Werte aufgefüllt.
Auch hier kann ich nicht sagen, ob dies dem Abfrageplaner bei einem schnelleren Plan für DISTINCT type
helfen würde ohne zu testen.