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
VOLATILEerstellt , aber es kannSTABLEsein . Per Dokumentation:Aufgrund dieses Snapshot-Verhaltens enthält eine Funktion nur
SELECTBefehle können bedenkenlos mitSTABLEgekennzeichnet werden .Verwandte:
- Wie man einen Parameter an eine Datumsfunktion übergibt
-
Sie verwenden auch
LANGUAGE plpgsqlstattsql, was sinnvoll ist, wenn Sie die Funktion mehrmals in derselben Sitzung ausführen. Aber dann müssen Sie es auchSTABLEmachen oder Sie verlieren diesen potenziellen Leistungsvorteil. Nochmal die Anleitung:STABLEundIMMUTABLEFunktionen 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
EXPLAINAusgabe zeigt einen Index Only Scan , kein sequenzieller Scan, wie Sie in Ihrem Kommentar vermuten. -
Es gibt auch einen Sortierschritt in Ihrem
EXPLAINAusgabe, die nicht mit dem angezeigten Code übereinstimmt. Sind Sie sicher, dass Sie den richtigenEXPLAINkopiert haben Ausgang? Wie hast du es überhaupt bekommen? PL/pgSQL-Funktionen sind Black Boxes, dieEXPLAINwerden müssen . Haben Sieauto_explainverwendet? ? 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 10hinzu wie ich es jetzt oben getan habe. Und erneut testen.