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
SELECT
les 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 plpgsql
au 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 rendreSTABLE
ou vous perdez cet avantage potentiel en termes de performances. Le manuel une fois de plus :STABLE
etIMMUTABLE
les 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
EXPLAIN
la 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
EXPLAIN
sortie qui ne correspond pas au code que vous affichez. Êtes-vous sûr d'avoir copié le bonEXPLAIN
production? 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 10
comme je l'ai fait maintenant ci-dessus. Et testez à nouveau.