Postgres - Funktionen werden mit deklarierten Volatilität Klassifizierung VOLATILE
, STABLE
oderIMMUTABLE
. Es ist bekannt, dass das Projekt mit diesen Bezeichnungen für integrierte Funktionen sehr streng ist. Und das aus gutem Grund. Prominentes Beispiel: Ausdrucksindizes erlauben nur IMMUTABLE
Funktionen und diese müssen wirklich unveränderlich sein, um falsche Ergebnisse zu vermeiden.
Benutzerdefinierte Funktionen können weiterhin nach Wahl des Eigentümers deklariert werden. Das Handbuch empfiehlt:
Um optimale Optimierungsergebnisse zu erzielen, sollten Sie Ihre Funktionen mit der strengsten Volatilitätskategorie kennzeichnen, die für sie gültig ist.
... und fügt eine umfangreiche Liste von Dingen hinzu, die mit einem falschen Volatilitätsetikett schief gehen können.
Dennoch gibt es Fälle, in denen eine Fälschung der Unveränderlichkeit sinnvoll ist. Meistens, wenn Sie wissen, dass die Funktion in Ihrem Anwendungsbereich tatsächlich unveränderlich ist. Beispiel:
Abgesehen von allen möglichen Auswirkungen auf die Datenintegrität , wie wirkt sich dies auf die Leistung aus? Man könnte annehmen , eine Funktion deklarieren IMMUTABLE
kann nur von Vorteil sein , die Leistung . Ist das so?
Kann die Angabe der Funktionsvolatilität IMMUTABLE
die Leistung beeinträchtigen ?
Nehmen wir an, dass das aktuelle Postgres 10 eingrenzt, aber alle neueren Versionen sind von Interesse.
quelle
FORCE
sie so oder so zu erreichen. 100% der erfahrenen PostgreSQL-Datenbankadministratoren arbeiten daran, diese Benutzeroberfläche mit Wrapper-Funktionen zu umgehen. Zumindest mitFORCE
würden wir keine Wrapper brauchen und wir müssten uns nicht auf die erklärte Volatilität von fn stützen.FORCE
, dass Ausdrucksindizes nicht unveränderliche Funktionen akzeptieren sollen (während sie als potenzieller Fehlerpunkt markiert werden). Ja, das scheint eine elegantere Lösung zu sein als unveränderliche Funktions-Wrapper.Antworten:
Ja, dies kann die Leistung beeinträchtigen.
Einfache SQL-Funktionen können in der aufrufenden Abfrage "eingebunden" werden. Zitieren des Postgres-Wikis :
Meine kühne Betonung.
Um die Richtigkeit durchzusetzen, gibt es eine Reihe von Voraussetzungen. Einer von ihnen :
Das heißt, SQL-Funktionen, die nicht unveränderliche Funktionen verwenden, aber noch deklariert
IMMTUTABLE
werden, sind von dieser Optimierung ausgeschlossen. Ausgelöst durch diese verwandten Antworten auf SO habe ich umfangreiche Tests durchgeführt:Grundsätzlich werden diese beiden Varianten einer einfachen SQL-Funktion verglichen (Zuordnen von Daten zu einem
integer
, Ignorieren des Jahres, das für den Zweck keine Rolle spielt):Die Postgres-Funktion
to_char()
ist nurSTABLE
nichtIMMUTABLE
(alle überladenen Instanzen davon - aus Gründen, die über den Rahmen dieser Antwort hinausgehen ). Der zweite ist also eine FälschungIMMUTABLE
und stellt sich in einem einfachen Test als 5x langsamer heraus :db <> hier fummeln
Dieses spezielle Beispiel kann durch das Äquivalent ersetzt werden:
Würde scheint teurer mit zwei Funktionsaufrufen und mehr Berechnungen. Aber das
IMMUTABLE
Etikett ist wahr (plus, ist die verwendete Funktion schneller und Nötigungtext
zuinteger
teurer, auch).2x so schnell wie die oben genannte schnellere Variante (10x so schnell wie die langsamere). Der Punkt ist: Verwenden Sie
IMMUTABLE
Funktionen, wo dies möglich ist , dann müssen Sie zunächst nicht "schummeln".quelle
STABLE
ist auch Inlining. Ich dachte, der Optimierer würde nur Online-IMMUTABLE
Funktionen.VOLATILE
genausogut.