*PostgreSQL-Leistungsproblem: Die „(func()).“-Syntax und redundante Funktionsaufrufe**
Dieser Artikel untersucht ein Leistungsproblem in PostgreSQL im Zusammenhang mit der (func()).*
-Syntax bei Verwendung mit Funktionen, die zusammengesetzte Typen oder Mengen zurückgeben. Die ursprüngliche Beobachtung, die in der folgenden Abfrage gezeigt wird, verdeutlicht das unerwartete Verhalten:
<code class="language-sql">SELECT (func(3)).*; -- Leads to multiple function calls</code>
Das Problem: Übermäßige Funktionsbewertungen
Das Kernproblem besteht darin, dass (func()).*
einen separaten Funktionsaufruf für jede Spalte in der Ausgabe der Funktion auslöst. Eine Funktion, die beispielsweise vier Spalten zurückgibt, könnte zu acht Funktionsaufrufen statt der erwarteten zwei führen. Dies steht in krassem Gegensatz zu alternativer Syntax, wie zum Beispiel:
<code class="language-sql">SELECT N, func(N); -- More efficient approach</code>
Lösung: Effizientes Umschreiben von Abfragen
Um die übermäßigen Aufrufe zu umgehen, bietet eine Unterabfrage einen Workaround. Obwohl dies im Allgemeinen effektiv ist, ist dies keine perfekte Lösung und kann zu anderen Leistungsaspekten führen.
Für PostgreSQL 9.3 und höher bietet das Schlüsselwort LATERAL
eine überlegene Lösung:
<code class="language-sql">SELECT mf.* FROM some_table LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>
Grundursache: PostgreSQL-Parser-Verhalten
Die Hauptursache liegt darin, wie der Parser von PostgreSQL mit dem Platzhalter *
innerhalb des Konstrukts (func()).*
umgeht. Die Wildcard-Erweiterung in einzelne Spalten beim Parsen ist die Ursache für die redundanten Funktionsaufrufe.
Leistungsbenchmark und Demonstration
Ein Beispiel für eine benutzerdefinierte Funktion zeigt die Leistungsdiskrepanz zwischen der problematischen Syntax und den vorgeschlagenen Problemumgehungen. Tests zeigen, dass der Unterabfrage-Ansatz (oder ein CTE) erhebliche Leistungsverbesserungen bietet.
Fazit: Optimierung von Abfragen in PostgreSQL
Während das Problem mit mehreren Funktionsaufrufen mit (func()).*
weiterhin ein bekanntes Verhalten ist, bieten die Problemumgehungen, insbesondere die Verwendung von LATERAL
(PostgreSQL 9.3), effektive Strategien für Entwickler, um die Abfrageleistung zu optimieren und unnötige Funktionsauswertungen zu reduzieren.
Das obige ist der detaillierte Inhalt vonWarum verursacht „(func()).*' in PostgreSQL mehrere Funktionsauswertungen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!