Geralmente, o planejador de consultas do Postgres não visualizações "inline" para otimizar toda a consulta. Por documentação:
Mas eu não acho que o Postgres seja inteligente o suficiente para concluir que ele pode alcançar o mesmo resultado da tabela base sem explodir linhas.
Você pode tentar esta consulta alternativa com um
LATERAL
Junte. É mais limpo: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;
Também deixa claro que um dos (
end_day
, start_day
) é redundante. Usando
LEFT JOIN
porque isso pode permitir que o planejador de consultas ignore a junção da sua consulta: SELECT DISTINCT type FROM v_mt_count_by_day;
Senão (com um
CROSS JOIN
ou INNER JOIN
) deve avalie a junção para ver se as linhas da primeira tabela são eliminadas. BTW, é:
SELECT DISTINCT type ...
não:
SELECT DISTINCT(type) ...
Observe que isso retorna uma
data
em vez do carimbo de data/hora em seu original. Mais fácil, e eu acho que é o que você quer de qualquer maneira? Requer Postgres 9.3+ Detalhes:
ROWS FROM
no Postgres 9.4+
Para explodir ambas as colunas em paralelo com segurança :
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;
O principal benefício:Isso não inviabilizaria para um produto cartesiano se os dois SRF não retornarem o mesmo número de linhas. Em vez disso, os valores NULL seriam preenchidos.
Novamente, não posso dizer se isso ajudaria o planejador de consultas com um plano mais rápido para
tipo DISTINCT
sem teste.