Vous pouvez y parvenir avec une simple fonction SQL. La fonctionnalité clé est la fonction 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; Appel :
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);
Ou la même chose avec un tableau littéral - ce qui est plus pratique dans certains contextes, notamment avec des instructions préparées :
SELECT * FROM f_attendance('{{1,1},{2,2}}');
La fonction toujours attend un tableau 2D. Même si vous passez une seule paire, imbriquez-la :
SELECT * FROM f_attendance('{{1,1}}');
Audit de votre implémentation
-
Vous avez créé la fonction
VOLATILE, mais il peut êtreSTABLE. Par documentation :En raison de ce comportement d'instantané, une fonction contenant uniquement
SELECTles commandes peuvent être marquées en toute sécuritéSTABLE.Connexe :
- Comment passer un paramètre dans une fonction de date
-
Vous utilisez également
LANGUAGE plpgsqlau lieu desql, ce qui est logique si vous exécutez la fonction plusieurs fois dans la même session. Mais alors vous devez aussi le rendreSTABLEou vous perdez cet avantage potentiel en termes de performances. Le manuel une fois de plus :STABLEetIMMUTABLEles fonctions utilisent un instantané établi au début de la requête appelante, tandis que les fonctions VOLATILES obtiennent un nouvel instantané au début de chaque requête qu'elles exécutent. -
Votre
EXPLAINla sortie affiche une analyse d'index uniquement , pas une analyse séquentielle comme vous le soupçonnez dans votre commentaire. -
Il y a aussi une étape de tri dans votre
EXPLAINsortie qui ne correspond pas au code que vous affichez. Êtes-vous sûr d'avoir copié le bonEXPLAINproduction? Comment l'avez-vous obtenu d'ailleurs ? Les fonctions PL/pgSQL sont des boîtes noires pourEXPLAIN. Avez-vous utiliséauto_explain? Détails :- Plan de requête Postgres d'une invocation UDF écrite en pgpsql
-
Le planificateur de requête Postgres n'a aucune idée du nombre d'éléments de tableau que le paramètre passé aura, il est donc difficile de planifier la requête et il peut s'agir par défaut d'une analyse séquentielle (en fonction de plusieurs facteurs). Vous pouvez aider en déclarant le nombre de lignes attendu. Si vous n'avez généralement pas plus de 10 éléments, ajoutez
ROWS 10comme je l'ai fait maintenant ci-dessus. Et testez à nouveau.