A rigor di termini, il termine "stored procedure" indica le procedure SQL in Postgres, introdotte con Postgres 11.
Ci sono anche funzioni che fanno quasi ma non esattamente la stessa cosa e che ci sono state fin dall'inizio.
Le funzioni con LANGUAGE sql
sono fondamentalmente solo file batch con semplici comandi SQL in un wrapper di funzioni (e quindi atomici, sempre eseguiti all'interno di una singola transazione) che accettano parametri. Tutte le istruzioni in una funzione SQL vengono pianificate contemporaneamente , il che è leggermente diverso dall'esecuzione di un'istruzione dopo l'altra e può influire sull'ordine in cui vengono eseguiti i blocchi.
Per di più, il linguaggio più maturo è PL / pgSQL ( LANGUAGE plpgsql
). Funziona bene ed è stato migliorato con ogni versione nell'ultimo decennio, ma serve come colla per i comandi SQL. Non è pensato per calcoli pesanti (tranne che con i comandi SQL).
Le funzioni PL / pgSQL eseguono query come istruzioni preparate . Il riutilizzo dei piani di query memorizzati nella cache elimina alcune spese generali di pianificazione e le rende un po 'più veloci delle equivalenti istruzioni SQL, il che può essere un effetto evidente a seconda delle circostanze. Potrebbe anche avere effetti collaterali come in questa domanda correlata:
Ciò comporta i vantaggi e gli svantaggi delle dichiarazioni preparate, come discusso nel manuale . Per query nelle tabelle con distribuzione irregolare dati e parametri variabili SQL dinamico con EXECUTE
può eseguire meglio quando il guadagno da un piano di esecuzione ottimizzata per il dato parametro (s) supera il costo di ri-pianificazione.
Poiché i piani di esecuzione generici di Postgres 9.2 sono ancora memorizzati nella cache per la sessione ma, citando il manuale :
Ciò si verifica immediatamente per le istruzioni preparate senza parametri; in caso contrario, si verifica solo dopo che cinque o più esecuzioni hanno prodotto piani la cui media dei costi stimati (incluso il sovraccarico di pianificazione) è più costosa della stima dei costi del piano generico.
Otteniamo il meglio da entrambi i mondi per la maggior parte del tempo (meno alcune spese generali aggiunte) senza (ab) utilizzare EXECUTE
. Dettagli in Novità di PostgreSQL 9.2 del Wiki PostgreSQL .
Postgres 12 introduce la variabile serverplan_cache_mode
aggiuntiva per forzare piani generici o personalizzati. Per casi speciali, usare con cura.
Puoi vincere alla grande con le funzioni lato server che impediscono ulteriori round trip al server di database dalla tua applicazione. Chiedi al server di eseguire il più possibile in una volta sola e restituisce solo un risultato ben definito.
Evitare l'annidamento di funzioni complesse, in particolare le funzioni di tabella ( RETURNING SETOF record
o TABLE (...)
). Le funzioni sono scatole nere che si pongono come barriere di ottimizzazione per il planner delle query. Sono ottimizzati separatamente, non nel contesto della query esterna, il che rende la pianificazione più semplice, ma può risultare in piani tutt'altro che perfetti. Inoltre, le dimensioni dei costi e dei risultati delle funzioni non possono essere previste in modo affidabile.
L' eccezione a questa regola sono le semplici funzioni SQL ( LANGUAGE sql
), che possono essere "incorporate" - se vengono soddisfatte alcune condizioni preliminari . Maggiori informazioni su come funziona il planner delle query in questa presentazione di Neil Conway (cose avanzate).
In PostgreSQL una funzione viene sempre eseguita automaticamente all'interno di una singola transazione . Tutto ha successo o niente. Se si verifica un'eccezione, viene eseguito il rollback di tutto. Ma c'è una gestione degli errori ...
Questo è anche il motivo per cui le funzioni non sono esattamente "stored procedure" (anche se quel termine viene usato talvolta, in modo fuorviante). Alcuni comandi piace VACUUM
, CREATE INDEX CONCURRENTLY
o CREATE DATABASE
non possono essere eseguiti all'interno di un blocco di transazione, quindi non sono consentiti nelle funzioni. (Nemmeno nelle procedure SQL, a partire da Postgres 11. Che potrebbe essere aggiunto in seguito.)
Ho scritto migliaia di funzioni plpgsql nel corso degli anni.