As funções PL / PgSQL e SQL simples fazem parte de um conjunto de ferramentas maior e devem ser visualizadas nesse contexto. Costumo pensar nisso em termos de uma escala crescente de poder combinada com complexidade e custo crescentes, onde você deve usar a ferramenta mais simples que fará o trabalho bem:
- Use visualizações sempre que possível
- Onde uma visualização não é adequada, use uma função SQL
- Onde uma função SQL não é adequada, use PL / PgSQL.
- Onde o PL / PgSQL for muito limitado ou pouco expressivo, use PL / Perl, PL / Python, PL / V8, PL / Java ou qualquer que seja sua preferência
- ... e onde nenhum PL fará o trabalho, use um programa externo e, possivelmente,
LISTEN
e NOTIFY
converse com ele.
Com muita frequência, uma visualização é suficiente quando você acha que uma função é necessária. Mesmo que seja extremamente caro para SELECT
toda a exibição, as WHERE
cláusulas na consulta que faz referência à exibição geralmente são inseridas na exibição e podem resultar em planos de consulta muito diferentes. Muitas vezes, tive grandes melhorias de desempenho ao converter funções SQL em visualizações.
O horário principal em que você descobre que não pode usar uma visualização e deve considerar uma função SQL é quando:
- Parâmetros que não podem ser expressos como
WHERE
cláusulas simples são necessários, como um parâmetro dentro de uma WITH
expressão
- Você deseja uma barreira de segurança por meio de uma
SECURITY DEFINER
função, e as security_barrier
visualizações no PostgreSQL 9.2 e superior não são suficientes para suas necessidades;
- Você precisa de parâmetros que não sejam incluídos em sub-cláusulas de uma exibição pelo otimizador e deseja controlá-la mais diretamente; ou
- Existem muitos parâmetros ou muitas repetições, portanto, é impraticável escrever a consulta como uma visualização.
Para a maioria dessas tarefas, uma função SQL simples funciona bem e geralmente é mais fácil de ler do que PL / PgSQL. As funções SQL declaradas STABLE
ou IMMUTABLE
(e também não declaradas STRICT
ou SECURITY DEFINER
) também podem ser incorporadas na instrução de chamada. Isso elimina a sobrecarga da chamada de função e às vezes também pode resultar em enormes benefícios de desempenho quando uma condição WHERE na função de chamada é empurrada para baixo na função SQL pelo otimizador. Use funções SQL sempre que forem suficientes para a tarefa.
O principal momento em que as funções SQL não funcionam é quando você precisa de muita lógica. Se / then / else operações que você não pode expressar como CASE
instruções, muita reutilização de resultados calculados, criação de valores a partir de partes, manipulação de erros, etc. O PL / PgSQL é útil então. Escolha PL / PgSQL quando não puder usar funções SQL ou elas não são adequadas, como para:
- SQL dinâmico e DDL dinâmico por meio da
EXECUTE
instrução
- Quando você deseja
RAISE
erros / avisos para os logs ou clientes
- Quando você precisa de tratamento de exceções - pode interceptar e manipular erros com
EXCEPTION
blocos, em vez de a transação inteira terminar com erro
- Lógica condicional complexa que não se encaixa
CASE ... WHEN
muito bem
- Muita reutilização de valores calculados que você não pode ajustar
WITH
e CTEs
- Construindo registros dinâmicos
- Você precisa executar uma ação após produzir o conjunto de resultados
Com expressões comuns de tabela (CTEs), especialmente CTEs graváveis, WITH RECURSIVE
acho que uso o PL / PgSQL muito menos do que costumava, porque o SQL é muito mais expressivo e poderoso. Eu uso modos de exibição e funções simples do SQL muito mais agora. Vale lembrar que funções simples do SQL podem conter mais de uma instrução; a última instrução é o resultado da função.