Puoi ottenerlo con una semplice funzione SQL. La caratteristica fondamentale è la funzione 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;
Chiama:
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);
O lo stesso con un array letterale - che è più conveniente in alcuni contesti, soprattutto con dichiarazioni preparate:
SELECT * FROM f_attendance('{{1,1},{2,2}}');
La funzione sempre si aspetta un array 2D. Anche se passi una singola coppia, nidificala:
SELECT * FROM f_attendance('{{1,1}}');
Verifica della tua implementazione
-
Hai creato la funzione
VOLATILE
, ma può essereSTABLE
. Per documentazione:A causa di questo comportamento di snapshot, una funzione contenente solo
SELECT
i comandi possono essere contrassegnati in modo sicuroSTABLE
.Correlati:
- Come passare un parametro in una funzione data
-
Usi anche
LANGUAGE plpgsql
invece disql
, che ha senso se si esegue la funzione più volte nella stessa sessione. Ma poi devi anche renderloSTABLE
o perdi quel potenziale vantaggio in termini di prestazioni. Il manuale ancora una volta:STABLE
eIMMUTABLE
le funzioni utilizzano uno snapshot stabilito all'inizio della query chiamante, mentre le funzioni VOLATILE ottengono un nuovo snapshot all'inizio di ogni query che eseguono. -
Il tuo
EXPLAIN
l'output mostra una Scansione solo indice , non una scansione sequenziale come sospetti nel tuo commento. -
C'è anche un passaggio di ordinamento nel tuo
EXPLAIN
output che non corrisponde al codice mostrato. Sei sicuro di aver copiato ilEXPLAIN
corretto produzione? Come l'hai ottenuto comunque? Le funzioni PL/pgSQL sono scatole nere perEXPLAIN
. Hai usatoauto_explain
? Dettagli:- Piano di query Postgres di una chiamata UDF scritta in pgpsql
-
Il pianificatore di query di Postgres non ha idea di quanti elementi dell'array avrà il parametro passato, quindi è difficile pianificare la query e potrebbe utilizzare per impostazione predefinita una scansione sequenziale (a seconda di più fattori). Puoi aiutare dichiarando il numero previsto di righe. Se in genere non hai più di 10 articoli aggiungi
ROWS 10
come ho fatto ora sopra. E prova ancora.