Re: Probleme mit sehr langsamen Left Outer Join

Albe Laurenz <[email protected]> Wed, 2 Mar 2016 10:09:07 +0000
Newsgroups gmane.comp.db.postgresql.german
Message-ID <A737B7A37273E048B164557ADEF4A58B53805A87@ntex2010i.host.magwien.gv.at>
Robert J. Rotter schrieb:
> Hi, sorry der EXPLAIN ANALYZE hat ein wenig länger gedauert. Gute 57
> Stunden.
> 
>          QUERY PLAN
> ------------------------------------------------------------------------------------------------------
> --------------------------------------------------------------------------
>  Hash Right Join  (cost=43891.46..74562849.42 rows=1 width=302) (actual time=57760187.680..207029422.793 rows=1 loops=1)
>    Hash Cond: (eci.cid = cr.cid)
>    ->  Merge Join  (cost=43883.15..28736387.35 rows=3332833000 width=157) (actual time=153.804..206956782.687 rows=40063581 loops=1)
>          Merge Cond: (((c.cid)::text = (eci.cid)::text) AND (c.rid = eci.rid))
>          ->  Index Scan using pk_c on c2 c  (cost=0.56..4542612.58 rows=39802190 width=132) (actual time=0.048..55931323.269 rows=40063581 loops=1)
>          ->  Index Scan using pk_e1 on e1 eci  (cost=0.56..2938434.16 rows=41891849 width=40) (actual time=0.031..16125164.797 rows=40063582 loops=1)
>    ->  Hash  (cost=8.30..8.30 rows=1 width=4) (actual time=26.795..26.795 rows=1 loops=1)
>          Buckets: 1024  Batches: 1  Memory Usage: 1kB
>          ->  Index Only Scan using pk_table1 on table1 cr (cost=0.28..8.30 rows=1 width=4) (actual time=26.772..26.780 rows=1 loops=1)
>                Index Cond: (name = 'a_name'::text)
>                Heap Fetches: 1
>  Total runtime: 207029423.634 ms
> (12 rows)
> 
> Ich hoffe das war es wert. ;)
> 
> Ich hab auch nochmal die Zeilen gezählt:
> 
> schema2.c2 --> 40066021 rows
> schema1.e1 --> 40066169 rows
> schema1.table1 --> 7408 rows

Versuch einmal die Abfrage umzuschreiben:

SELECT ...
FROM schema1.table1 cr
   LEFT OUTER JOIN
     schema1.e1 eci ON cr.c_id = eci.cid
   LEFT OUTER JOIN
     schema2.c2 c ON c.c2id::text = eci.c2id::text AND c.r1 = eci.r1;

In der Select-Liste müssen halt alle Spalten von "eci" durch NULL
ersetzt werden, wenn der Primary Key von "c" NULL ist; etwa statt
   schema1.func1(eci.rid, eci.cid)
muß es heißen
   schema1.func1(CASE WHEN c.pkey IS NULL THEN NULL ELSE eci.rid END,
                 CASE WHEN c.pkey IS NULL THEN NULL ELSE eci.cid END)

Ich bin nicht sicher, aber da insgesamt nur eine Zeile herauskommt,
könnte der erste LEFT OUTER JOIN schon eine kleine Ergebnismenge haben
und das ganze mit einem Nested Loop Join schnell erledigt werden können.

Es muß hat einen Index auf e1(cid, ...) geben.

Liebe Grüße,
Laurenz Albe

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