En general, el planificador de consultas de Postgres lo hace vistas "en línea" para optimizar toda la consulta. Por documentación:
Pero no creo que Postgres sea lo suficientemente inteligente para concluir que puede llegar al mismo resultado desde la tabla base sin explotar filas.
Puedes probar esta consulta alternativa con un LATERAL
unirse. Es más limpio:
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;
También deja claro que uno de (end_day
, start_day
) es redundante.
Usando LEFT JOIN
porque eso podría permitir que el planificador de consultas ignore la combinación de su consulta:
SELECT DISTINCT type FROM v_mt_count_by_day;
De lo contrario (con un CROSS JOIN
o INNER JOIN
) debe evalúe la combinación para ver si se eliminan las filas de la primera tabla.
Por cierto, es:
SELECT DISTINCT type ...
no:
SELECT DISTINCT(type) ...
Tenga en cuenta que esto devuelve una date
en lugar de la marca de tiempo en su original. Más fácil, ¿y supongo que es lo que quieres de todos modos?
Requiere Postgres 9.3+ Detalles:
ROWS FROM
en PostgreSQL 9.4+
Explotar ambas columnas en paralelo de forma segura :
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;
El principal beneficio:esto no descarrilaría en un producto cartesiano si los dos SRF no devuelven el mismo número de filas. En su lugar, se rellenarían los valores NULL.
Nuevamente, no puedo decir si esto ayudaría al planificador de consultas con un plan más rápido para DISTINCT type
sin pruebas.