Le funzioni PL / PgSQL e SQL semplice fanno entrambe parte di un set di strumenti più ampio e devono essere visualizzate in tale contesto. Tendo a pensarci in termini di una scala crescente di potenza abbinata a complessità e costi crescenti, dove dovresti usare lo strumento più semplice che farà bene il lavoro:
- Usa le viste ove possibile
- Dove una vista non è adatta, utilizzare una funzione SQL
- Dove una funzione SQL non è adatta, utilizzare PL / PgSQL.
- Laddove PL / PgSQL è troppo limitato o non sufficientemente espressivo, utilizzare PL / Perl, PL / Python, PL / V8, PL / Java o qualunque sia la tua preferenza
- ... e dove nessun PL farà il lavoro, usa un programma esterno e possibilmente
LISTEN
e NOTIFY
per parlarci.
Molto spesso una vista è sufficiente quando si ritiene che sia necessaria una funzione. Anche se è estremamente costoso per SELECT
l'intera vista, le WHERE
clausole nella query che fanno riferimento alla vista vengono generalmente trasferite nella vista e possono comportare piani di query molto diversi. Ho spesso avuto grandi miglioramenti delle prestazioni dalla conversione delle funzioni SQL in visualizzazioni.
Il momento principale in cui trovi che non puoi usare una vista e dovresti considerare una funzione SQL è quando:
- Sono necessari parametri che non possono essere espressi come semplici
WHERE
clausole, come un parametro all'interno di WITH
un'espressione
- Volete una barriera di sicurezza tramite una
SECURITY DEFINER
funzione e le security_barrier
viste in PostgreSQL 9.2 e versioni successive non sono sufficienti per le vostre esigenze;
- Sono necessari parametri che non vengono inseriti nelle sotto-clausole di una vista dall'ottimizzatore e che si desidera controllarlo più direttamente; o
- Ci sono molti parametri o c'è molta ripetizione dei parametri, quindi non è pratico scrivere la query come vista.
Per la maggior parte di questi compiti, una semplice funzione SQL funziona bene ed è spesso più facile da leggere rispetto a PL / PgSQL. Le funzioni SQL dichiarate STABLE
o IMMUTABLE
(e non anche dichiarate STRICT
o SECURITY DEFINER
) possono anche essere incorporate nell'istruzione chiamante. Ciò elimina l'overhead della chiamata di funzione e talvolta può comportare enormi vantaggi in termini di prestazioni quando una condizione WHERE nella funzione di chiamata viene trasferita nella funzione SQL dall'ottimizzatore. Utilizzare le funzioni SQL ogni volta che sono sufficienti per l'attività.
Il momento principale in cui le funzioni SQL non eseguono il lavoro è quando è necessaria molta logica. Se / allora / else operazioni che non è possibile esprimere come CASE
istruzioni, un sacco di riutilizzo dei risultati calcolati, creazione di valori da blocchi, gestione degli errori, ecc., PL / PgSQL risulta utile. Scegli PL / PgSQL quando non puoi utilizzare le funzioni SQL o sono inadatte, come per:
- SQL dinamico e DDL dinamico tramite l'
EXECUTE
istruzione
- Quando si desidera
RAISE
errori / avvisi per i registri o il client
- Quando è necessaria la gestione delle eccezioni, è possibile intercettare e gestire gli errori con i
EXCEPTION
blocchi anziché interrompere l'intera transazione in caso di errore
- Logica condizionale complessa che non si adatta
CASE ... WHEN
molto bene
- Un sacco di riutilizzo di valori calcolati che non è possibile inserire
WITH
e CTE
- Creazione di record dinamici
- È necessario eseguire un'azione dopo aver prodotto il set di risultati
Con le espressioni di tabella comuni (CTE), in particolare i CTE scrivibili, WITH RECURSIVE
trovo che utilizzo PL / PgSQL molto meno di quanto non fossi prima perché SQL è molto più espressivo e potente. Uso molto di più viste e semplici funzioni SQL. Vale la pena ricordare che le semplici funzioni SQL possono contenere più di un'istruzione; l'ultima affermazione è il risultato della funzione.