Du kan uppnå det med en enkel SQL-funktion. Nyckelfunktion är funktionen 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;
Ring:
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);
Eller samma sak med en array literal - vilket är bekvämare i vissa sammanhang, särskilt med förberedda uttalanden:
SELECT * FROM f_attendance('{{1,1},{2,2}}');
Funktionen alltid förväntar sig en 2D-array. Även om du passerar ett enstaka par, kapsla det:
SELECT * FROM f_attendance('{{1,1}}');
Revision av din implementering
-
Du skapade funktionen
VOLATILE
, men det kan varaSTABLE
. Per dokumentation:På grund av detta ögonblicksbildbeteende, en funktion som endast innehåller
SELECT
kommandon kan säkert markeras medSTABLE
.Relaterat:
- Hur man skickar en parameter till en datumfunktion
-
Du använder också
LANGUAGE plpgsql
istället försql
, vilket är vettigt om du kör funktionen flera gånger i samma session. Men då måste du också göra denSTABLE
eller så förlorar du den potentiella prestationsfördelen. Manualen ännu en gång:STABLE
ochIMMUTABLE
funktioner använder en ögonblicksbild som upprättats vid starten av den anropande frågan, medan VOLATILE-funktioner får en ny ögonblicksbild i början av varje fråga de kör. -
Din
EXPLAIN
utdata visar en Endast indexsökning , inte en sekventiell genomsökning som du misstänker i din kommentar. -
Det finns också ett sorteringssteg i din
EXPLAIN
utdata som inte matchar koden du visar. Är du säker på att du kopierade rättEXPLAIN
produktion? Hur fick du det förresten? PL/pgSQL-funktioner är svarta rutor för attEXPLAIN
. Använde duauto_explain
? Detaljer:- Postgres-frågeplan för en UDF-anrop skriven i pgpsql
-
Postgres-frågeplaneraren har ingen aning om hur många arrayelement den skickade parametern kommer att ha, så det är svårt att planera frågan och den kan som standard använda en sekventiell skanning (beroende på fler faktorer). Du kan hjälpa till genom att deklarera det förväntade antalet rader. Om du vanligtvis inte har fler än 10 artiklar, lägg till
ROWS 10
som jag gjorde nu ovan. Och testa igen.