Re: temp tables and function performance

Поиск
Список
Период
Сортировка
От Alban Hertroys
Тема Re: temp tables and function performance
Дата
Msg-id 458664A8.4050609@magproductions.nl
обсуждение исходный текст
Ответ на temp tables and function performance  ("Anton Melser" <melser.anton@gmail.com>)
Список pgsql-general
Anton Melser wrote:
> Hi,
> I am trying to move up in the world with my sql and need to do the
> following...
> I have a subscribers table and I need to export to csv (semi-colon
> separated) certain fields - that is fine, but I also need to export a
> multi-select field from another table as one string (0 to n values
> separated by commas) per line. The problem being that to get the
> actual string I have to go via 4 other relations... and as I have
> 200k+ subscribers this takes a while.

200k isn't all that much, unless you have a lot of large columns.

> My idea (which seems to work, though I haven't tested fully as it
> takes too damn long!), was to do the following. I would REALLY
> appreciate any pointers as my sql has never been this challenged!
>
> CREATE OR REPLACE FUNCTION mytest()
>  RETURNS integer AS
> $BODY$DECLARE kindy INTEGER;
> BEGIN


> create temporary table tmp_interests(
> id bigint,
> value character varying(100)
> )
> WITHOUT OIDS
> ON COMMIT DROP;
>
> insert into tmp_interests
> select distinct si.subid, rbi.value
> from restem rbi, cats cc, trm_terms tt, subrest si
> where rbi.key = cc.name
>     and cc.catid = tt.modcid
>     and tt.tid = si.themeid;

You can do these in one go using
 CREATE TEMPORARY TABLE tmp_interests AS SELECT ...

> create temporary table tmp_subscribers(
> email character varying(200),
> format character varying(4),
> interests  character varying(1000),
> )
> WITHOUT OIDS
> ON COMMIT DROP;
>
> insert into tmp_subscribers
> Select email,
> format,
> my_interests(id) as interests
> from subscriber;
>
> GET DIAGNOSTICS kindy = ROW_COUNT;
>
> copy tmp_subscribers to '/home/myname/subs.csv' WITH CSV DELIMITER AS
> ';' NULL AS '';

If you have PG8.2 and can combine your 2 select queries into one, then
you can create a view of them and copy that instead. It takes out all
the inserts and can use your already existing table statistics - it
should be faster.

Also, after inserting a bunch of records into a table, make a habit of
running ANALYSE on it. Otherwise the query-planner knows nothing about
the data in the tables and is likely to come up with a sub-optimal query
plan.

>
> GET DIAGNOSTICS kindy = ROW_COUNT;
>
> return kindy;
>
> END;$BODY$
>  LANGUAGE 'plpgsql' VOLATILE;
>
> ...
>
>
> CREATE OR REPLACE FUNCTION my_interests(bigint)
>  RETURNS character varying AS
> $BODY$DECLARE
> subid ALIAS FOR $1;
> interests character varying;
> myinterest RECORD;
>
> BEGIN
>     interests := '';
>     FOR myinterest IN execute 'select value from tmp_interests where id =
> ' || subid LOOP

No need for a dynamic query here...

>         if interests = '' then
>             interests := myinterest.value;
>         else
>             interests := interests || ',' || myinterest.value;
>         end if;
>     END LOOP;
>
>     RETURN interests;
> END$BODY$
>  LANGUAGE 'plpgsql' VOLATILE;

I'd have to look up the syntax, but I'm quite certain you can put the
results of a select into an array. After that you can call
array_to_string(...) to convert it into a comma seperated string. That'd
take away the need for this SP (which I think is actually STABLE instead
of VOLATILE).

--
Alban Hertroys
alban@magproductions.nl

magproductions b.v.

T: ++31(0)534346874
F: ++31(0)534346876
M:
I: www.magproductions.nl
A: Postbus 416
   7500 AK Enschede

// Integrate Your World //

В списке pgsql-general по дате отправления:

Предыдущее
От: Alban Hertroys
Дата:
Сообщение: Re: Stored Procedure and Trigger they puzzle me
Следующее
От: "riki"
Дата:
Сообщение: Re: installing postgres on win Me...