Обсуждение: slow SP with temporary tables, any idea of solution?

Поиск
Список
Период
Сортировка

slow SP with temporary tables, any idea of solution?

От
Pavel Stehule
Дата:
Hello

I have very slow SP this type:
BEGIN CREATE TEMP TABLE xxx ON COMMIT DROP(); WHILE n > 0 LOOP -- n >> 0   FOR _r IN EXECUTE 'SELECT ...' LOOP
RETURNNEXT _r;     EXECUTE 'UPDATE xxx SET item = 1 WHERE id = '||_r.id;     n := n - 1;   END LOOP; END LOOP;
 
END;

The main problem is too much EXECUTE commands. My first idea wos 
substitute it PREPARED plans. But PREPARED plans are compiled when 
procedure is first time lunched, and I can't easy use it form temp tables. 
I can change PREPARE upd UPDATE item SET .. to EXECUTE 'PREPARE upd 
UPDATE..' and I really saved some time. But this method isn't possible for 
cmd FOR  

I have two possibility solution (before ending successfull solution for SP 
and temporary tables). First, the time for really preparing command will 
be really time of executing PREPARE command. Second, PREPARE can accept 
string parametr like EXECUTE command. But all is inpossible now.

Can you help me other possibilities?
Thank you
Pavel Stehule



Re: slow SP with temporary tables, any idea of solution?

От
Tom Lane
Дата:
Pavel Stehule <stehule@kix.fsv.cvut.cz> writes:
> Can you help me other possibilities?

Create the temp table only once per connection (you can use ON COMMIT
DELETE ROWS instead of ON COMMIT DROP to clean it out).  Then you won't
need to use EXECUTE.
        regards, tom lane


Re: slow SP with temporary tables, PLPGSQL problems

От
Pavel Stehule
Дата:
> Pavel Stehule <stehule@kix.fsv.cvut.cz> writes:
> > Can you help me other possibilities?
> 
> Create the temp table only once per connection (you can use ON COMMIT
> DELETE ROWS instead of ON COMMIT DROP to clean it out).  Then you won't
> need to use EXECUTE.
> 
I am not sure so it's possible. I use persistent connect via PHP. There 
isn't trigger for new connect. But I found same problem as you. PL/pgSQL 
can't    FOR r IN EXPLAIN SELECT ..  FOR r IN EXECUTE 'EXECUTE plan()'

I rewrite SP, and I have only one SELECT without two, 20% time less, but 
it's not readable code. I don't know how much work or if its possible move 
compilation time for PREPARE on every processing of this command. I think 
so its more natural for cmd PREPARE. But in this part of PL/pgSQL are more 
problems:

CREATE OR REPLACE FUNCTION foo() RETURNS SETOF varchar AS $$
DECLARE r RECORD;
BEGIN PREPARE se(date) AS SELECT * FROM queue WHERE activated = $1; FOR r IN EXECUTE se(CURRENT_DATE) LOOP   RETUTRN
NEXTr.activated; END LOOP; DEALLOCATE se; RETURN;
 
END; $$ LANGUAGE plpgsql;

is this code correct? I think yes. But isn't true. I get message: function 
se(date) does not exist CONTEXT: SQL statement "SELECT se(CURRENT_DATE)".

Is only theory: FOR rn IN EXECUTE 'EXECUTE se(CURRENT_DATE)' LOOP
Now I get error: cannot open non-SELECT query as cursor. Prepared commands 
are good idea, but I cant use its now.

I have Pg 8.0.1

Regards
Pavel Stehule



Re: slow SP with temporary tables, PLPGSQL problems

От
Pavel Stehule
Дата:
> > Create the temp table only once per connection (you can use ON COMMIT
> > DELETE ROWS instead of ON COMMIT DROP to clean it out).  Then you won't
> > need to use EXECUTE.
> > 
I am sorry, first time I didn't understand. Now I did some test and its 
good adivice. Sometimes I have problem understand so I can use temp. 
tables on an level of connection and its not neccesery push temp tables on 
SP level. If I don't change structure of temp tables (and its unpropably 
on produstion database) I haven't problems. I have still one question. 
What is possible so I can

CREATE OR REPLACE FONCTION foo() ..
BEGIN CREATE TEMP TABLE xxx(... INSERT INTO xxx VALUES (... 

It's works, but in time of compilation SP temp table xxx doesn't exists. 
It's mean so Id in cmd INSERT is little bit dynamic? 

I rewrite my SP and I have one notice: In documentation is note, so 
TRUNCATE TABLE is faster then DELETE FROM. It's not true for small temp 
tables. On my computer TRUNCATE needs 100ms and DELETE 8ms. It's general 
or any exception?

Thank You
Pavel Stehule