PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

É possível responder a consultas em uma visualização antes de materializá-la totalmente?


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.