Les fonctions Postgres sont déclarées avec une classification de volatilité VOLATILE
, STABLE
ouIMMUTABLE
. Le projet est connu pour être très strict avec ces étiquettes pour les fonctions intégrées. Et pour cause. Exemple frappant: les index d'expression n'autorisent que les IMMUTABLE
fonctions et celles-ci doivent être vraiment immuables pour éviter des résultats incorrects.
Les fonctions définies par l'utilisateur sont toujours libres d'être déclarées selon le choix du propriétaire. Le manuel conseille:
Pour de meilleurs résultats d'optimisation, vous devez étiqueter vos fonctions avec la catégorie de volatilité la plus stricte qui leur est valable.
... et ajoute une longue liste de choses qui peuvent mal tourner avec une étiquette de volatilité incorrecte.
Pourtant, il existe des cas où la simulation de l'immuabilité a un sens. Surtout quand vous savez que la fonction est, en fait, immuable dans votre portée. Exemple:
Toutes les implications possibles sur l'intégrité des données mises à part , quel est l'effet sur les performances? On pourrait supposer que déclarer une fonction IMMUTABLE
ne peut être que bénéfique pour les performances . Est-ce vrai?
La déclaration de la volatilité des fonctions peut-elle IMMUTABLE
nuire aux performances?
Supposons que Postgres 10 actuel le réduise, mais toutes les versions récentes sont intéressantes.
la source
FORCE
les deux cas. 100% des administrateurs de bases de données PostgreSQL expérimentés mentent pour contourner cette interface utilisateur avec des fonctions d'encapsulation. Au moins avecFORCE
, nous n'aurions pas besoin de wrappers et nous n'aurions pas à mentir sur la volatilité fn déclarée.FORCE
c'est censé faire en sorte que les index d'expression acceptent des fonctions non immuables (tout en les marquant comme point de défaillance potentiel). Oui, cela semble être une solution plus élégante que les wrappers de fonctions immuables.Réponses:
Oui, cela peut nuire aux performances.
Les fonctions SQL simples peuvent être "intégrées" dans la requête appelante. Citant le wiki Postgres :
Accentuation sur moi.
Pour imposer l'exactitude, il existe un certain nombre de conditions préalables. L'un d'eux :
Autrement dit, les fonctions SQL utilisant des fonctions non immuables mais toujours déclarées
IMMTUTABLE
sont exclues de cette optimisation. Déclenché par ces réponses connexes sur SO, j'ai effectué des tests approfondis:Comparaison de base de ces deux variantes d'une fonction SQL simple (mappage des dates sur an
integer
, en ignorant l'année qui n'a pas d'importance à cet effet):La fonction Postgres
to_char()
est seulementSTABLE
, pasIMMUTABLE
(toutes les instances surchargées - pour des raisons qui dépassent le cadre de cette réponse ). Donc, le second est fauxIMMUTABLE
et s'avère 5 fois plus lent dans un test simple:db <> violon ici
Cet exemple spécifique peut être remplacé par l'équivalent:
Cela semblerait plus cher avec deux appels de fonction et plus de calculs. Mais l'
IMMUTABLE
étiquette est vrai (plus, la fonction utilisée est plus rapide et contraindretext
àinteger
est plus cher aussi).2x plus rapide que la variante la plus rapide ci-dessus (10x plus rapide que la plus lente). Le point étant: utilisez des
IMMUTABLE
fonctions lorsque cela est possible , vous n'avez pas à "tricher" pour commencer.la source
STABLE
également significatif. Je pensais que l'optimiseur neIMMUTABLE
fonctionnerait qu'en ligne .VOLATILE
tout aussi bien.