Re: Decrease the time required function

From: Kevin Grittner <kgrittn(at)ymail(dot)com>
To: Albe Laurenz <laurenz(dot)albe(at)wien(dot)gv(dot)at>, "kescobar(at)estudiantes(dot)uci(dot)cu" <kescobar(at)estudiantes(dot)uci(dot)cu>, "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: Re: Decrease the time required function
Date: 2013-02-08 18:40:43
Message-ID: 1360348843.54284.YahooMailNeo@web162903.mail.bf1.yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Albe Laurenz <laurenz(dot)albe(at)wien(dot)gv(dot)at> wrote:
> Karel Riverón wrote:

>> I have a PL/pgSQL function that it takes 4 seconds to execute.

>> OPEN casos_reales;
>> LOOP FETCH casos_reales into cr;
> [...]
>>     OPEN criterios;
>>     LOOP FETCH criterios into c;
> [...]
>>         SELECT c_r_c.id, valor INTO crc
>>         FROM caso_real_criterio c_r_c, caso_real c_r,criterio c_
> [...]
>>         SELECT c_e_c.id, valor INTO cec
>>         FROM caso_escenario_criterio c_e_c, caso_escenario c_e,criterio c_
> [...]
>>     END LOOP;
> [...]
>> END LOOP;
>
> I did not study your processing in detail, but it looks
> like most of that could be expressed as a single
> SQL statement that joins the four tables

+1

On a quick look, it seems like someting along these lines might be
what you want (although I had to guess a little at schema, since
you didn't show it):

SELECT cr.*
  FROM (SELECT sum(impactos) AS sum_impactos FROM criterio) si
  CROSS JOIN criterio c
  JOIN caso_real_criterio crc ON (crc.criterio_id = c.id)
  JOIN caso_real cr ON (cr.id = crc.caso_real_id)
  JOIN caso_escenario_criterio cec ON (cec.criterio_id = c.id)
  JOIN caso_escenario ce ON (ce.id = cec.caso_escenario_id)
  WHERE ce.id = escenario_id
  GROUP BY cr.id
  HAVING sum(c.impacto * (1 - abs(crc.valor - cec.valor) / 5))
           / si.sum_impactos >= 0.75
;

You might need to adjust the GROUP BY clause if you're not running
a recent major release.  If you want to keep it as a function, you
can throw out the DECLARE section and everything between the
outermost BEGIN and END, and replace it with RETURN QUERY and the
above query, or turn it into a SQL function to avoid the overhead
of materializing the entire result set.

If you get some form of that to run, please post back with a
comparison of run times.

-Kevin

In response to

Browse pgsql-general by date

  From Date Subject
Next Message AI Rumman 2013-02-08 20:23:35 no implicit cast error in 9.2?
Previous Message Adrian Klaver 2013-02-08 18:13:34 Re: DROP OWNED BY fails to drop privileges granted by non-owners (was Re: [GENERAL] Bug, Feature, or what else?)