Das erreichen Sie mit einer einfachen SQL-Funktion. Hauptmerkmal ist die Funktion generate_subscripts()
:
CREATE OR REPLACE FUNCTION f_attendance(_arr2d int[])
RETURNS SETOF attendance AS
$func$
SELECT a.*
FROM generate_subscripts($1, 1) i
JOIN attendance a ON a.class = $1[i][1]
AND a.section = $1[i][2]
$func$ LANGUAGE ROWS 10 sql STABLE;
Aufruf:
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);
Oder dasselbe mit einem Array literal - was in manchen Zusammenhängen bequemer ist, besonders bei vorbereiteten Anweisungen:
SELECT * FROM f_attendance('{{1,1},{2,2}}');
Die Funktion immer erwartet ein 2D-Array. Auch wenn Sie ein einzelnes Paar übergeben, verschachteln Sie es:
SELECT * FROM f_attendance('{{1,1}}');
Audit Ihrer Implementierung
-
Sie haben die Funktion
VOLATILE
erstellt , aber es kannSTABLE
sein . Per Dokumentation:Aufgrund dieses Snapshot-Verhaltens enthält eine Funktion nur
SELECT
Befehle können bedenkenlos mitSTABLE
gekennzeichnet werden .Verwandte:
- Wie man einen Parameter an eine Datumsfunktion übergibt
-
Sie verwenden auch
LANGUAGE plpgsql
stattsql
, was sinnvoll ist, wenn Sie die Funktion mehrmals in derselben Sitzung ausführen. Aber dann müssen Sie es auchSTABLE
machen oder Sie verlieren diesen potenziellen Leistungsvorteil. Nochmal die Anleitung:STABLE
undIMMUTABLE
Funktionen verwenden einen Snapshot, der zu Beginn der aufrufenden Abfrage erstellt wird, während VOLATILE-Funktionen einen frischen Snapshot am Beginn jeder von ihnen ausgeführten Abfrage erhalten. -
Ihr
EXPLAIN
Ausgabe zeigt einen Index Only Scan , kein sequenzieller Scan, wie Sie in Ihrem Kommentar vermuten. -
Es gibt auch einen Sortierschritt in Ihrem
EXPLAIN
Ausgabe, die nicht mit dem angezeigten Code übereinstimmt. Sind Sie sicher, dass Sie den richtigenEXPLAIN
kopiert haben Ausgang? Wie hast du es überhaupt bekommen? PL/pgSQL-Funktionen sind Black Boxes, dieEXPLAIN
werden müssen . Haben Sieauto_explain
verwendet? ? Einzelheiten:- Postgres-Abfrageplan eines in pgpsql geschriebenen UDF-Aufrufs
-
Der Postgres-Abfrageplaner hat keine Ahnung, wie viele Array-Elemente der übergebene Parameter haben wird, daher ist es schwierig, die Abfrage zu planen, und es kann standardmäßig ein sequenzieller Scan verwendet werden (abhängig von weiteren Faktoren). Sie können helfen, indem Sie die erwartete Anzahl von Zeilen angeben. Wenn Sie normalerweise nicht mehr als 10 Elemente haben, fügen Sie
ROWS 10
hinzu wie ich es jetzt oben getan habe. Und erneut testen.