Estou tentando entender o impacto no desempenho da seleção de dados em uma exibição, onde uma das colunas em uma exibição é função de outros dados na tabela original.
O cálculo é executado independentemente de a coluna computada estar ou não na lista de colunas selecionadas?
Se eu tivesse uma mesa e a vista declarasse assim
CREATE TABLE price_data (
ticker text, -- Ticker of the stock
ddate date, -- Date for this price
price float8, -- Closing price on this date
factor float8 -- Factor to convert this price to USD
);
CREATE VIEW prices AS
SELECT ticker,
ddate,
price,
factor,
price * factor as price_usd
FROM price_data
Oxalá que multiplicação ser realizada em uma consulta como a abaixo?
select ticker, ddate, price, factor from prices
Existe uma referência que garanta desta forma ou de outra? Eu estava lendo a documentação do sistema de regras no Postgres, mas acho que a resposta realmente está no otimizador, pois nada na documentação do sistema de regras indicava que ele não seria selecionado.
Suspeito que, no caso acima, o cálculo não seja realizado. Alterei a visualização para usar a divisão em vez da multiplicação e inseri um 0
for factor
em price_data
. A consulta acima não falhou, mas se a consulta foi modificada para selecionar a coluna computada, a consulta modificada falhou.
Existe alguma maneira de entender quais cálculos estão sendo feitos quando a select
é realizado? Acho que estou procurando algo parecido, EXPLAIN
mas que também me fale sobre os cálculos que estão sendo executados.
fonte
Respostas:
Como @Laurenz disse, sua análise está correta: o otimizador evitará avaliar expressões de coluna que não afetam o resultado da consulta (e sua tentativa de forçar um erro de divisão por zero é prova disso).
Isso depende de quais colunas você está selecionando, mas também da categoria de volatilidade das expressões da coluna. O otimizador é livre para omitir
immutable
estable
chamadas de função se sua saída nunca for usada, pois elas não podem afetar o resultado, mas asvolatile
funções podem ter efeitos colaterais, portanto, elas não são tão facilmente otimizadas.Por exemplo:
Se apenas a
volatile
coluna estiver selecionada:... então, como você pode ver,
stable_function()
está ausente naexplain
saída e a falta de umaNOTICE
confirma que esta chamada foi otimizada.No entanto, se a
stable
coluna estiver selecionada:... então vemos as duas expressões de coluna aparecendo no plano e os
NOTICE
s mostram que ambas as funções foram executadas.Parece não haver nenhuma menção explícita a esse comportamento nos documentos, portanto, não há garantias concretas sobre se uma expressão será avaliada ou não e você não deve confiar nos efeitos colaterais que suas chamadas de função possam ter.
Mas se sua única preocupação é desempenho, desde que você marque suas funções como
stable
ouimmutable
onde apropriado, você pode estar razoavelmente certo (especialmente em casos simples como este) de que elas não serão avaliadas a menos que sejam necessárias.(E enquanto você estiver lá auditando suas declarações de volatilidade, também poderá definir os sinalizadores de segurança paralelos .)
fonte
Sua suspeita está correta e o cálculo não deve ser realizado se a coluna não for usada.
Para confirmar isso, observe a saída de
EXPLAIN (VERBOSE)
para a consulta, que mostrará as colunas retornadas.fonte