Hi everyone,

I have a PL/pgSQL function that it takes 4 seconds to execute. This is my function:

CREATE OR REPLACE FUNCTION listarcasosrecuperados(escenario_id integer)
  RETURNS SETOF caso_real AS
$BODY$

DECLARE

    criterios CURSOR FOR SELECT * FROM criterio;

    casos_reales CURSOR FOR SELECT * FROM caso_real;

    sum_impactos NUMERIC DEFAULT 0;

    sum_impacto_modulo NUMERIC DEFAULT 0;

    impacto NUMERIC DEFAULT 0;

    valor_caso_real_criterio NUMERIC DEFAULT 0;

    valor_caso_escenario_criterio NUMERIC DEFAULT 0;

    s NUMERIC DEFAULT 0.0;

    c RECORD;

    cr RECORD;

    crc RECORD;

    cec RECORD;

    casos_escenarios_criterios RECORD;

    casos_reales_criterios RECORD;

BEGIN

/*
 * RECORRER CURSOR DE CRITERIOS Y
 * SUMATORIA DE LOS IMPACTOS DE LOS CRITERIOS
 */
OPEN criterios;

LOOP FETCH criterios into c;

IF NOT FOUND THEN
    EXIT;
ELSE
    sum_impactos := sum_impactos + c.impacto;
END IF;

END LOOP;

CLOSE criterios;

/*
 * OBTENER CRITERIOS DEL CASO ESCENARIO PASADO POR PARAMETRO
 */

SELECT * INTO casos_escenarios_criterios FROM caso_escenario_criterio WHERE caso_escenario_id = $1;

/*
 * RECORRER CURSOR DE CASOS REALES *
 */
BEGIN
OPEN casos_reales;

LOOP FETCH casos_reales into cr;

IF NOT FOUND THEN
    EXIT;
ELSE
    sum_impacto_modulo := 0;

    impacto := 0;

    valor_caso_real_criterio := 0;

    valor_caso_escenario_criterio := 0;

    /*
    * OBTENER CRITERIOS DEL CASO REAL EN CUESTIÓN
    */

SELECT * INTO casos_reales_criterios FROM caso_real_criterio WHERE caso_real_id = cr.id;

    OPEN criterios;

    LOOP FETCH criterios into c;

    IF NOT FOUND THEN
        EXIT;
    ELSE

        SELECT c_r_c.id, valor INTO crc
        FROM caso_real_criterio c_r_c, caso_real c_r,criterio c_
        WHERE c_.id = c_r_c.criterio_id
        AND c_.id = c.id
        AND c_r_c.caso_real_id = c_r.id
        AND c_r.id = cr.id;

        valor_caso_real_criterio := crc.valor;

        SELECT c_e_c.id, valor INTO cec
        FROM caso_escenario_criterio c_e_c, caso_escenario c_e,criterio c_
        WHERE c_.id = c_e_c.criterio_id
        AND c_.id = c.id
        AND c_e_c.caso_escenario_id = c_e.id
        AND c_e.id = escenario_id;

        valor_caso_escenario_criterio := cec.valor;

        impacto := c.impacto;

sum_impacto_modulo := sum_impacto_modulo + impacto * (1 - abs(valor_caso_real_criterio - valor_caso_escenario_criterio)/5);

    END IF;

    END LOOP;

    CLOSE criterios;

    s := sum_impacto_modulo / sum_impactos;

    IF s >= 0.75 THEN
           RETURN NEXT cr;
        END IF;

END IF;

END LOOP;

CLOSE casos_reales;

END;

END

$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;
ALTER FUNCTION listarcasosrecuperados(integer)
  OWNER TO postgres;

I need to decrease the time required function. Please, anyone helpme.

Regards, Karel Riverón
Students Scientific Council
Informatics Science University


Reply via email to