Probleme mit sehr langsamen Left Outer Join

"Robert J. Rotter" <[email protected]> Fri, 26 Feb 2016 17:57:42 +0100
Newsgroups gmane.comp.db.postgresql.german
Message-ID <OF5058320D.6D98D5AB-ONC1257F65.005AA867-C1257F65.005D2C5F@notes.denic.de>
Hallo,

ich benötige mal einen Tipp von der Postgres Community:

Ich habe ein Query, das von einer Applikation abgesetzt wird was sehr, 
sehr lange dauert. 
Wohl mehrere Stunden, ich habe es nicht zu Ende laufen lassen.

Die Query sieht wie folgt aus (Schema-, Tabellen- und Spaltennamen habe 
ich abgeändert):

select <diverse spalten> from schema1.table1 cr
left outer join 
schema1.view1 co on cr.c_id = co.cId 
where name = 'name1';

wobei der view1 die folgende Form besitzt:

CREATE OR REPLACE VIEW schema1.view1 AS 
 SELECT <c.columns>,
        <eci.columns>,
    schema1.func1(eci.rid, eci.cid) AS p1,
    schema1.func2(eci.rid, eci.cid) AS p2,
    schema1.func3(eci.rid, eci.cid) AS p3,
    <c. columns>,
    <eci. columns> 
   FROM schema2.c2 c,
    schema1.e1 eci
  WHERE c.c2id::text = eci.c2id::text AND c.r1 = eci.r1;

Die Funktionen sind alle ähnlich, fragen nur unterschiedliche Tabellen 
über den pk ab:

CREATE OR REPLACE FUNCTION schema1.func1(id integer, code character 
varying)
  RETURNS SETOF text AS
$BODY$
    declare numberOfRows int4;
    begin
       numberOfRows := (select count(*) from schema2.ce1 where rid = id 
and cid = code);
       if (numberOfRows = 1) then
            return query select e1::text as e1 from schema2.ce1 where rid 
= id and cid = code;
       end if;
       if (numberOfRows > 1) then
            return query select string_agg(e1::text, chr(10)) AS e from 
schema2.ce1 where rid = id and cid = code group by rid, cid;
       end if;
       if (numberOfRows = 0) then
           return query (select null::text as e);
       end if;
    end;
$BODY$

Folgender Query Plan kommt dabei raus:

                                                        QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
 Hash Right Join  (cost=40591.59..69079304.13 rows=1 width=302)
   Hash Cond: (eci.cid = cr.cid)
   ->  Merge Join  (cost=40583.28..26603909.55 rows=3089119000 width=157)
         Merge Cond: (((c.cid)::text = (eci.cid)::text) AND (c.rid = 
eci.rid))
         ->  Index Scan using pk_c on c2 c  (cost=0.56..4190454.15 
rows=38920217 width=132)
         ->  Index Scan using pk_e1 on e1 eci  (cost=0.56..2702272.47 
rows=38828501 width=40)
   ->  Hash  (cost=8.30..8.30 rows=1 width=4)
         ->  Index Only Scan using pk_table1 on table1 cr (cost=0.28..8.30 
rows=1 width=4)
               Index Cond: (name = 'a_name'::text)
(9 rows)


Ich sehe hier schon, daß viele Rows beteiligt sind. 
Jedoch fehlt mir ein wenig der Ansatz, wie ich das beschleunigen kann bzw. 
warum es so langsam ist. 
Kann mir da jemand einen Tip geben?

Danke schonmal.



Viele Grüße

Robert



-- 
Sent via pgsql-de-allgemein mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-de-allgemein