Ogólnie rzecz biorąc, planer zapytań Postgres tak widoki „wbudowane”, aby zoptymalizować całe zapytanie. Według dokumentacji:
Ale nie sądzę, żeby Postgres był wystarczająco inteligentny aby stwierdzić, że może osiągnąć ten sam wynik z tabeli podstawowej bez rozbijania wierszy.
Możesz wypróbować to alternatywne zapytanie z LATERAL
Przystąp. Jest czystszy:
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;
Wyjaśnia również, że jeden z (end_day
, dzień_rozpoczęcia
) jest zbędne.
Używanie LEFT JOIN
ponieważ może to pozwolić planistowi zapytań zignorować sprzężenie z zapytania:
SELECT DISTINCT type FROM v_mt_count_by_day;
Inny (z CROSS JOIN
lub DOŁĄCZENIE WEWNĘTRZNE
) musi oceń połączenie, aby zobaczyć, czy wiersze z pierwszej tabeli zostały wyeliminowane.
Przy okazji, to:
SELECT DISTINCT type ...
nie:
SELECT DISTINCT(type) ...
Zauważ, że zwraca to datę
zamiast sygnatury czasowej w oryginale. Łatwiej, a myślę, że i tak tego chcesz?
Wymaga Postgresa 9.3+ Szczegóły:
ROWS FROM
w Postgresie 9.4+
Aby rozbić obie kolumny równolegle bezpiecznie :
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;
Główna korzyść:nie spowoduje to wykolejenia się na produkt kartezjański, jeśli dwa SRF nie zwracają tej samej liczby wierszy. Zamiast tego zostaną uzupełnione wartości NULL.
Ponownie nie mogę powiedzieć, czy pomogłoby to planerowi zapytań z szybszym planem dla typu DISTINCT
bez testowania.