Guillermo E. Villanueva escribió:

> Qué pasa si la función a llamar tiene parámetros que dependen de cada fila
> de la consulta, por ejemplo :
> create or replace function fn_test(x int) returns int
> language plpgsql as
> $$
> begin raise notice 'buu!';
> return x*4;
> end
> $$;
> 
> select fn_test(price::int),price
> from products p2
> where fn_test(price::int) > 6
> limit 100;
> 
> en ese caso puedo hacer algo para llamar a la función una sola vez por cada
> fila? solo se me ocurre un cálculo auxiliar con subconsulta a nivel de
> from, pero termina siendo mas complejo para el motor que ejecutar dos veces
> la función por cada fila :-)

Puedes usar una subconsulta con una "barrera de optimización".  Primero
pones la subconsulta, que da esto:

select fn, price
  from (select fn_test(price) as fn, price from products) AS sc
 where fn > 6
 LIMIT 100;

Pero eso puede no darte el resultado que quieres porque el optimizador
"aplana" la subconsulta convirtiéndola en parte de la consulta externa,
o sea que los "fn" de la consulta externa igual se convierten en la
invocación de fn_test(price).  Para evitar eso agregas una barrera de
optimización que es OFFSET 0:

select fn, price
  from (select fn_test(price) as fn, price from products OFFSET 0) AS sc
 where fn > 6
 LIMIT 100;

Eso le quita libertad al optimizador.


-- 
Álvaro Herrera                https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Reply via email to