Heim >Datenbank >MySQL-Tutorial >Wie verhindert man mehrere Funktionsaufrufe bei Verwendung von „(func()).*' in SQL-Abfragen?

Wie verhindert man mehrere Funktionsaufrufe bei Verwendung von „(func()).*' in SQL-Abfragen?

Linda Hamilton
Linda HamiltonOriginal
2025-01-10 11:51:42572Durchsuche

How to Prevent Multiple Function Calls When Using `(func()).*` in SQL Queries?

Vermeiden wiederholter Funktionsaufrufe mit (func()).* in SQL-Abfragen

Beim 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.

Das Problem

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.

Lösungen

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>

Ursache

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn