Las funciones de Postgres se declaran con clasificación de volatilidad VOLATILE, STABLEoIMMUTABLE . Se sabe que el proyecto es muy estricto con estas etiquetas para las funciones integradas. Y con buen motivo. Ejemplo destacado: los índices de expresión solo permiten IMMUTABLEfunciones y esas deben ser verdaderamente inmutables para evitar resultados incorrectos.
Las funciones definidas por el usuario aún pueden declararse libremente según lo elija el propietario. El manual aconseja:
Para obtener los mejores resultados de optimización, debe etiquetar sus funciones con la categoría de volatilidad más estricta que sea válida para ellas.
... y agrega una extensa lista de cosas que pueden salir mal con una etiqueta de volatilidad incorrecta.
Aún así, hay casos en los que tiene sentido falsificar la inmutabilidad. Principalmente cuando sabe que la función es, de hecho, inmutable dentro de su alcance. Ejemplo:
Dejando a un lado todas las posibles implicaciones en la integridad de los datos , ¿cuál es el efecto en el rendimiento? Se podría suponer que declarar una función IMMUTABLEsolo puede ser beneficiosa para el rendimiento . ¿Es eso así?
¿La declaración de volatilidad de la función puede IMMUTABLE dañar el rendimiento?
Supongamos que Postgres 10 actual lo reduce, pero todas las versiones recientes son de interés.
fuente

FORCEcualquier manera. El 100% de los DBA PostgreSQL experimentados mienten para evitar esa interfaz de usuario con funciones de contenedor. Al menos conFORCE, no necesitaríamos envoltorios y no tendríamos que mentir sobre la volatilidad declarada de fn.FORCEse supone que los índices de expresión aceptan funciones no inmutables (al tiempo que los marcan como posibles puntos de falla). Sí, eso parecería una solución más elegante que los envoltorios de funciones inmutables.Respuestas:
Sí, puede dañar el rendimiento.
Las funciones SQL simples se pueden "en línea" en la consulta de llamada. Citando el Wiki de Postgres :
El énfasis audaz es mío.
Para hacer cumplir la corrección, hay una serie de condiciones previas. Uno de ellos :
Es decir, las funciones SQL que utilizan funciones no inmutables pero que aún se declaran
IMMTUTABLEestán excluidas de esta optimización. Activado por estas respuestas relacionadas en SO, he estado realizando pruebas exhaustivas:Básicamente, comparando estas dos variantes de una función SQL simple (asignando fechas a una
integer, ignorando el año que no importa para ese propósito):La función Postgres
to_char()es únicaSTABLE, noIMMUTABLE(todas las instancias sobrecargadas de la misma, por razones más allá del alcance de esta respuesta ). Entonces, el segundo es falsoIMMUTABLEy resulta ser 5 veces más lento en una prueba simple:db <> violín aquí
Este ejemplo específico se puede reemplazar con el equivalente:
Sería parecer más caro con dos llamadas a funciones y más cálculos. Sin embargo, la
IMMUTABLEetiqueta es verdadera (además, la función de uso es más rápido y coaccionartextaintegeres más caro, también).2 veces más rápido que la variante más rápida anterior (10 veces más rápido que el más lento). El punto es: usar
IMMUTABLEfunciones cuando sea posible , para no tener que "hacer trampa".fuente
STABLEtambién está en línea. Pensé que el optimizador soloIMMUTABLEfuncionaría en línea .VOLATILEigual de bien.