On Wednesday, February 06, 2013 12:22:36 PM Guillermo E. Villanueva wrote:

Buen dato Alvaro, muchas gracias, voy a probarlo


Guillermo Villanueva




El 6 de febrero de 2013 12:20, Alvaro Herrera <alvhe...@2ndquadrant.com> 
escribió:

Guillermo E. Villanueva escribió:

> Respondiendome a mi mismo he visto en algunos foros que lo resuelven con
> una subconsulta a nivel del from algo así como:
>
> select
>     col_1,
>     col_2,

>     *col_result*,
>     case when *col_result* > 0 then 'L' else 'D' END col_4

> from
> (
>   select
>       col_1,
>       col_2,

>       fn_funciondeusuario(parametros) *col_result*,

>   from
>       tablas
> ) as tablas2    ;
>
> Mi intención era evitar que postgres haga el cálculo dos veces por cada
> tupla del resultado, entonces reformulo mi pregunta si lo hago así:
> select
>     col_1,
>     col_2,

>     fn_funciondeusuario(parametros) *col_result*,

>     case when fn_funciondeusuario(parametros) > 0 then 'L' else 'D' END
> col_4
> from
>     tablas;
>
> Postgres calcula 1 o 2 veces por cada tupla?


Haz la prueba -- pon un RAISE NOTICE en la función y ve cuantas veces
aparece.  Fíjate qué sucede si marcas la función como VOLATILE, STABLE o
IMMUTABLE.

El optimizador está autorizado (no necesariamente lo hará) a optimizar
llamados a funciones no VOLATILE cuando aparezcan más de una vez para la
misma tupla.

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

Sugerencia - CTE's :

WITH tablaVirtual AS (
select
    col_1,
    col_2,
    fn_funciondeusuario(parametros)  *col_result*,
from
    tablas;
)
SELECT  col_1,col2, *col_result*,  case when *col_result* > 0 then 'L' else 
'D' END col_4 FROM tablaVirtual;

Probablemente no habrá diferencia en la ejecución, pero quizá es más claro de 
esta manera.
-- 
postgresql.org.mx

Responder a