Puede lograr eso con una simple función SQL. La característica clave es la función 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;
Llamar:
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);
O lo mismo con un arreglo literal - lo cual es más conveniente en algunos contextos, especialmente con declaraciones preparadas:
SELECT * FROM f_attendance('{{1,1},{2,2}}');
La función siempre espera una matriz 2D. Incluso si pasa un solo par, anídelo:
SELECT * FROM f_attendance('{{1,1}}');
Auditoría de su implementación
-
Hiciste la función
VOLATILE
, pero puede serSTABLE
. Por documentación:Debido a este comportamiento de instantáneas, una función que contiene solo
SELECT
los comandos se pueden marcar con seguridadSTABLE
.Relacionado:
- Cómo pasar un parámetro a una función de fecha
-
También usa
LANGUAGE plpgsql
en lugar desql
, lo que tiene sentido si ejecuta la función varias veces en la misma sesión. Pero luego también debes hacerloSTABLE
o pierde ese beneficio potencial de rendimiento. El manual una vez más:STABLE
yIMMUTABLE
Las funciones utilizan una instantánea establecida al inicio de la consulta de llamada, mientras que las funciones VOLÁTILES obtienen una instantánea nueva al comienzo de cada consulta que ejecutan. -
Su
EXPLAIN
la salida muestra un Exploración de índice solamente , no un escaneo secuencial como sospechas en tu comentario. -
También hay un paso de clasificación en su
EXPLAIN
salida que no coincide con el código que muestra. ¿Estás seguro de haber copiado elEXPLAIN
correcto? ¿producción? ¿Cómo lo obtuviste de todos modos? Las funciones PL/pgSQL son cajas negras paraEXPLAIN
. ¿Usasteauto_explain
? ? Detalles:- Plan de consulta de Postgres de una invocación de UDF escrita en pgpsql
-
El planificador de consultas de Postgres no tiene idea de cuántos elementos de la matriz tendrá el parámetro pasado, por lo que es difícil planificar la consulta y puede ser un escaneo secuencial predeterminado (dependiendo de más factores). Puede ayudar declarando el número esperado de filas. Si normalmente no tiene más de 10 elementos, agregue
ROWS 10
como lo hice ahora arriba. Y vuelve a probar.