Strictement parlant, le terme "procédures stockées" désigne des procédures SQL dans Postgres, introduites avec Postgres 11. Lié:
Il y a aussi des fonctions qui font presque mais pas tout à fait la même chose et qui existent depuis le début.
Les fonctions avec ne LANGUAGE sql
sont fondamentalement que des fichiers de commandes avec des commandes SQL simples dans un wrapper de fonctions (et donc atomiques, toujours exécutées dans une transaction unique ) acceptant des paramètres. Toutes les instructions d'une fonction SQL sont planifiées en même temps , ce qui diffère légèrement de l'exécution d'une instruction après l'autre et peut affecter l'ordre dans lequel les verrous sont utilisés.
Pour n'importe quoi de plus, le langage le plus mature est PL / pgSQL ( LANGUAGE plpgsql
). Cela fonctionne bien et a été amélioré avec chaque version au cours de la dernière décennie, mais cela sert surtout de colle pour les commandes SQL. Il n'est pas destiné aux calculs lourds (autres qu'avec des commandes SQL).
Les fonctions PL / pgSQL exécutent des requêtes telles que des instructions préparées . La réutilisation de plans de requête en cache permet de réduire les coûts liés à la planification et de les rendre un peu plus rapides que les instructions SQL équivalentes, ce qui peut avoir un effet notable en fonction des circonstances. Il peut également avoir des effets secondaires comme dans cette question connexe:
Ceci comporte les avantages et les inconvénients des déclarations préparées - comme indiqué dans le manuel . Pour les requêtes sur les tables avec la distribution des données irrégulières et des paramètres variables SQL dynamique avec EXECUTE
peut effectuer mieux lorsque le gain d'un plan d'exécution optimisé pour le paramètre donné (s) l' emporte sur le coût de la replanification.
Depuis Postgres 9.2, les plans d’exécution génériques sont toujours mis en cache pour la session mais, citant le manuel :
Cela se produit immédiatement pour les instructions préparées sans paramètres; sinon, cela se produit uniquement après que cinq exécutions ou plus ont généré des plans dont le coût moyen estimé (y compris les frais généraux de planification) est plus coûteux que l'estimation du coût générique du plan.
Nous obtenons le meilleur des deux mondes la plupart du temps (moins quelques frais généraux ajoutés) sans (ab) utiliser EXECUTE
. Détails dans Nouveautés dans PostgreSQL 9.2 du wiki PostgreSQL .
Postgres 12 introduit la variable serveurplan_cache_mode
supplémentaire pour forcer les plans génériques ou personnalisés. Pour les cas spéciaux, utilisez avec précaution.
Vous pouvez gagner gros avec des fonctions côté serveur qui empêchent des allers-retours supplémentaires vers le serveur de base de données à partir de votre application. Demandez au serveur d’exécuter autant que possible à la fois et ne renvoie qu’un résultat bien défini.
Évitez d'imbriquer des fonctions complexes, en particulier des fonctions de table ( RETURNING SETOF record
ou TABLE (...)
). Les fonctions sont des boîtes noires qui constituent des barrières d'optimisation pour le planificateur de requêtes. Elles sont optimisées séparément, pas dans le contexte de la requête externe, ce qui simplifie la planification, mais peut entraîner des plans moins que parfaits. En outre, le coût et la taille des résultats des fonctions ne peuvent pas être prédits de manière fiable.
Les exceptions à cette règle sont les simples fonctions SQL ( LANGUAGE sql
), qui peuvent être "intégrées" - si certaines conditions préalables sont remplies . En savoir plus sur le fonctionnement du planificateur de requêtes dans cette présentation de Neil Conway (fonctions avancées).
Dans PostgreSQL, une fonction est automatiquement exécutée dans une seule transaction . Tout cela réussit ou rien. Si une exception se produit, tout est annulé. Mais il y a la gestion des erreurs ...
C'est aussi pour cette raison que les fonctions ne sont pas exactement des "procédures stockées" (même si ce terme est parfois utilisé, de manière trompeuse). Certaines commandes telles que VACUUM
, CREATE INDEX CONCURRENTLY
ou CREATE DATABASE
ne peuvent pas être exécutées à l'intérieur d'un bloc de transaction, elles ne sont donc pas autorisées dans les fonctions. (Ni dans les procédures SQL, à ce jour, à partir de Postgres 11. Cela pourrait être ajouté plus tard.)
J'ai écrit des milliers de fonctions plpgsql au fil des ans.