(func()).*
in SQL-AbfragenBeim Einsatz von Funktionen, die Tabellen oder zusammengesetzte Typen zurückgeben, kann die (func(arg)).*
-Syntax zu redundanten Funktionsaufrufen für jede Ausgabespalte führen. Dieses Problem tritt auf, wenn Funktionen innerhalb von Tabellen oder Unterabfragen aufgerufen werden, wobei (func()).*
oft der einzige praktische Ansatz ist.
Unerwarteterweise löst (func()).*
mehrere Funktionsausführungen aus – eine Zahl, die der Anzahl der Ausgabespalten entspricht. Beispielsweise könnte eine Funktion, die vier Spalten zurückgibt, acht Mal statt der erwarteten zwei aufgerufen werden.
Um dies zu beheben, kapseln Sie den Funktionsaufruf in einer Unterabfrage:
<code class="language-sql">SELECT (mf).* FROM ( SELECT my_func(x) AS mf FROM some_table ) sub;</code>
Dadurch werden im Allgemeinen zusätzliche Funktionsaufrufe vermieden und keine zusätzlichen Laufzeitscans eingeführt. Für absolute Sicherheit sollten Sie den OFFSET 0
-Trick in Betracht ziehen oder die Einschränkungen von PostgreSQL bei der CTE-Optimierung nutzen:
<code class="language-sql">SELECT (mf).* FROM ( SELECT my_func(x) AS mf FROM some_table OFFSET 0 ) sub; WITH tmp(mf) AS ( SELECT my_func(x) FROM some_table ) SELECT (mf).* FROM tmp;</code>
PostgreSQL 9.3 und spätere Versionen bieten eine elegantere Lösung mit LATERAL
:
<code class="language-sql">SELECT mf.* FROM some_table LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>
Die zugrunde liegende Ursache ist die Erweiterung von (func()).*
durch den Parser in eine Spaltenliste. Der analysierte Baum zeigt, dass sich (func(x)).*
in Folgendes verwandelt:
<code>(my_func(x)).i, (my_func(x)).j, (my_func(x)).k, (my_func(x)).l</code>
Dieses ineffiziente Knotenklonen anstelle einer einzelnen Funktionsaufrufknotenreplikation führt zu wiederholten Aufrufen.
Das obige ist der detaillierte Inhalt vonWie verhindert man mehrere Funktionsaufrufe bei Verwendung von „(func()).*' in SQL-Abfragen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!