sql >> Base de Datos >  >> RDS >> PostgreSQL

Pasar múltiples conjuntos o matrices de valores a una función

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

  1. Hiciste la función VOLATILE , pero puede ser STABLE . Por documentación:

    Debido a este comportamiento de instantáneas, una función que contiene solo SELECT los comandos se pueden marcar con seguridad STABLE .

    Relacionado:

    • Cómo pasar un parámetro a una función de fecha
  2. También usa LANGUAGE plpgsql en lugar de sql , lo que tiene sentido si ejecuta la función varias veces en la misma sesión. Pero luego también debes hacerlo STABLE o pierde ese beneficio potencial de rendimiento. El manual una vez más:

    STABLE y IMMUTABLE 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.

  3. Su EXPLAIN la salida muestra un Exploración de índice solamente , no un escaneo secuencial como sospechas en tu comentario.

  4. 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 el EXPLAIN correcto? ¿producción? ¿Cómo lo obtuviste de todos modos? Las funciones PL/pgSQL son cajas negras para EXPLAIN . ¿Usaste auto_explain? ? Detalles:

    • Plan de consulta de Postgres de una invocación de UDF escrita en pgpsql
  5. 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.