Las funciones PL / PgSQL y SQL simple son parte de un conjunto de herramientas más grande y deben verse en ese contexto. Tiendo a pensarlo en términos de una escala ascendente de potencia combinada con la complejidad y el costo ascendentes, donde debería usar la herramienta más simple que hará bien el trabajo:
- Use vistas siempre que sea posible
- Cuando una vista no es adecuada, use una función SQL
- Cuando una función SQL no es adecuada, use PL / PgSQL.
- Donde PL / PgSQL es demasiado limitado o no lo suficientemente expresivo, use PL / Perl, PL / Python, PL / V8, PL / Java, o lo que sea que prefiera
- ... y donde ningún PL hará el trabajo, use un programa externo y posiblemente
LISTEN
y NOTIFY
para hablar con él.
Con frecuencia, una vista es suficiente cuando cree que se necesita una función. Incluso si es extremadamente costoso para SELECT
toda la vista, las WHERE
cláusulas en la consulta que hacen referencia a la vista generalmente se introducen en la vista y pueden generar planes de consulta muy diferentes. A menudo he tenido grandes mejoras de rendimiento al convertir funciones SQL en vistas.
El momento principal en el que encuentra que no puede usar una vista y debe considerar una función SQL es cuando:
WHERE
Se necesitan parámetros que no se puedan expresar como cláusulas simples , como un parámetro dentro de una WITH
expresión
- Desea una barrera de seguridad mediante una
SECURITY DEFINER
función, y las security_barrier
vistas en PostgreSQL 9.2 y superiores no son suficientes para sus necesidades;
- Necesita parámetros que el optimizador no empuje hacia abajo en las subcláusulas de una vista y desea controlarlo más directamente; o
- Hay muchos parámetros o hay muchas repeticiones de los parámetros, por lo que no es práctico escribir la consulta como una vista.
Para la mayoría de esas tareas, una función SQL simple funciona bien y, a menudo, es más fácil de leer que PL / PgSQL. Las funciones SQL declaradas STABLE
o IMMUTABLE
(y no también declaradas STRICT
o SECURITY DEFINER
) también se pueden incluir en la instrucción de llamada. Eso elimina la sobrecarga de la llamada a la función y, a veces, también puede generar grandes beneficios de rendimiento cuando el optimizador empuja una condición WHERE en la función de llamada hacia la función SQL. Utilice las funciones de SQL siempre que sean suficientes para la tarea.
El momento principal en que las funciones de SQL no harán el trabajo es cuando necesita mucha lógica. Si / luego / otras operaciones que no puede expresar como CASE
declaraciones, mucha reutilización de los resultados calculados, la creación de valores a partir de fragmentos, manejo de errores, etc. PL / PgSQL es útil entonces. Elija PL / PgSQL cuando no pueda usar las funciones de SQL o no encajen bien, como por ejemplo:
- SQL dinámico y DDL dinámico a través de la
EXECUTE
declaración
- Cuando desee
RAISE
errores / advertencias para los registros o el cliente
- Cuando necesite manejo de excepciones: puede atrapar y manejar errores con
EXCEPTION
bloques en lugar de hacer que toda la transacción finalice en caso de error
- Lógica condicional compleja que no encaja
CASE ... WHEN
muy bien
- Gran cantidad de reutilización de valores calculados en los que no puede encajar
WITH
y CTE
- Construyendo registros dinámicos
- Debe realizar una acción después de generar el conjunto de resultados.
Con expresiones de tabla comunes (CTE), especialmente CTE de escritura y WITH RECURSIVE
encuentro que uso PL / PgSQL mucho menos de lo que solía porque SQL es mucho más expresivo y poderoso. Utilizo vistas y funciones SQL simples mucho más ahora. Vale la pena recordar que las funciones SQL simples pueden contener más de una declaración; La última declaración es el resultado de la función.