Thread: SETOF performance

SETOF performance

From
Jeff
Date:
I think it was on this list - someone posted a  message about SETOF
being slower.  Tom replied saying it was because it needed to create an
on-disk tuplestore.

I was just looking for some clarification - a SETOF function will
always write the reslting tuples to disk (Not buffering in say a
sort_mem sized buffer)?

I think if that is the case I may need to go back and change some stuff
around.
I have a procedure that I broke out a bit to make life easier.

Basically it goes

for v_row in
    select blah from function_that_gets_data_from_some_cache(....)
    rowcount := rowcount + 1;
    return next v_row;
end for;

if rowcount = 0 then
    [same thing, but we call some_function_that_creates_data_for_cache]
end if;

Doing it this way means I avoid having to deal with it in the client
and I also avoid having a giant stored procedure. (I like short & sweet
things)

What I've found for timings is this:

select * from function_that_gets_data_from_some_cache() runs around 1.8
ms
but select * from the_top_level_function() runs around 4.2ms
(Yes, I know 4.2 ms is fast, but that is not the point).

could this overhead be related to the SETOF tuplestores?

Might it be better to use refcursor or something or bite the bullet and
live with a giant procedure?

--
Jeff Trout <jeff@jefftrout.com>
http://www.jefftrout.com/
http://www.stuarthamm.net/


Re: SETOF performance

From
Joe Conway
Date:
Jeff wrote:
> I think it was on this list - someone posted a  message about SETOF
> being slower.  Tom replied saying it was because it needed to create an
> on-disk tuplestore.
>
> I was just looking for some clarification - a SETOF function will always
> write the reslting tuples to disk (Not buffering in say a sort_mem sized
> buffer)?

I think at least part of what you're seeing is normal function call
overhead. As far as tuplestores writing to disk, here's what the source
says:

In src/backend/utils/sort/tuplestore.c
8<---------------------------------------
  * maxKBytes: how much data to store in memory (any data beyond this
  * amount is paged to disk).  When in doubt, use work_mem.
  */
Tuplestorestate *
tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
8<---------------------------------------

In src/backend/executor/execQual.c:ExecMakeTableFunctionResult():
8<---------------------------------------
tupstore = tuplestore_begin_heap(true, false, work_mem);
8<---------------------------------------

So up to work_mem (sort_mem in 7.4 and earlier) should be stored in memory.

Joe