Pregunta de principiante:
Tengo una función costosa f(x, y)
en dos columnas x e y en mi tabla de base de datos.
Quiero ejecutar una consulta que me da el resultado de la función como una columna y le impone una restricción, algo así como
SELECT *, f(x, y) AS func FROM table_name WHERE func < 10;
Sin embargo, esto no funciona, así que tendré que escribir algo como
SELECT *, f(x, y) AS func FROM table_name WHERE f(x, y) < 10;
¿Funcionará esto la costosa función dos veces? ¿Cuál es la mejor manera de hacer esto?
postgresql
postgresql-9.4
Veintiuno
fuente
fuente
STABLE
/IMMUTABLE
oVOLATILE
?Respuestas:
Creemos una función que tenga un efecto secundario para que podamos ver cuántas veces se ejecuta:
Y luego llama a esto como lo haces:
Como puede ver, la función se llama al menos una vez (de la
WHERE
cláusula), y cuando la condición es verdadera, una vez más para producir la salida.Para evitar la segunda ejecución, puede hacer lo que sugiere Edgar , es decir, ajustar la consulta y filtrar el conjunto de resultados:
Para verificar aún más cómo funciona esto, uno puede ir
pg_stat_user_functions
y verificarcalls
allí (dadotrack_functions
se establece en 'todos).Probemos con algo que no tenga efectos secundarios:
simple()
en realidad es demasiado simple, por lo que puede estar en línea , por lo tanto, no aparece en la vista. Hagámoslo insalvable:Como se ve, la imagen es la misma con o sin efectos secundarios.
Cambiar
other_one()
aIMMUTABLE
cambia el comportamiento (quizás sorprendentemente) a peor, ya que se llamará 13 veces en ambas consultas.fuente
Intenta llamarlo de nuevo:
fuente