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,
LISTENe NOTIFYconverse 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 SELECTtoda a exibição, as WHEREclá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
WHEREcláusulas simples são necessários, como um parâmetro dentro de uma WITHexpressão
- Você deseja uma barreira de segurança por meio de uma
SECURITY DEFINERfunção, e as security_barriervisualizaçõ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 STABLEou IMMUTABLE(e também não declaradas STRICTou 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 CASEinstruçõ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
EXECUTEinstrução
- Quando você deseja
RAISEerros / avisos para os logs ou clientes
- Quando você precisa de tratamento de exceções - pode interceptar e manipular erros com
EXCEPTIONblocos, em vez de a transação inteira terminar com erro
- Lógica condicional complexa que não se encaixa
CASE ... WHENmuito bem
- Muita reutilização de valores calculados que você não pode ajustar
WITHe 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 RECURSIVEacho 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.