Re: MERGE: performance advices - Mailing list pgsql-general
| From | Steve Clark |
|---|---|
| Subject | Re: MERGE: performance advices |
| Date | |
| Msg-id | 48BD6E25.4050507@netwolves.com Whole thread Raw |
| In response to | Re: MERGE: performance advices ("Richard Broersma" <richard.broersma@gmail.com>) |
| Responses |
Re: MERGE: performance advices
|
| List | pgsql-general |
Richard Broersma wrote:
> On Tue, Sep 2, 2008 at 8:10 AM, Steve Clark <sclark@netwolves.com> wrote:
>
>
>>Is there a way to do something similar with the following? I am an SQL noob
>>and the
>>following takes longer to run than is reasonable, on the order of hours.
>>
>>insert into myevents select * from t_unit_event_log a where exists
>> (select b.event_log_no from myevents b
>> where a.event_status = 1 and a.event_ref_log_no IS NOT NULL
>> and a.event_ref_log_no = b.event_log_no and a.event_log_no not
>>in
>> (select event_log_no from myevents)
>> )
>
>
>
> To start off with, this SQL statement can be refined a bit. Many of
> the sub-query WHERE clause constraints have nothing to do with the
> Correlated sub-query. The refinement would look like so:
>
> INSERT INTO Myevents
> SELECT *
> FROM T_unit_event_log AS A
> WHERE A.event_status = 1
> AND A.event_ref_log_no IS NOT NULL
> AND A.event_log_no NOT IN ( SELECT event_log_no
> FROM Myevents)
> AND EXISTS ( SELECT B.event_log_no
> FROM Myevents AS B
> WHERE A.event_ref_log_no = B.event_log_no );
>
>
> The next step would be to rework the NOT IN sub-query into a LEFT JOIN
> WHERE IS NULL;
>
> INSERT INTO Myevents
> SELECT *
> FROM T_unit_event_log AS A
> LEFT JOIN Myevents AS C
> ON A.event_log_no = C.event_log_no
> WHERE A.event_status = 1
> AND A.event_ref_log_no IS NOT NULL
> AND C.event_log_no IS NULL
> AND EXISTS ( SELECT B.event_log_no
> FROM Myevents AS B
> WHERE A.event_ref_log_no = B.event_log_no );
>
> There is one possible alteration that may or many not improve
> performance. This would be to replace the EXISTS with a LEFT JOIN
> WHERE IS NOT NULL;
>
> INSERT INTO Myevents
> SELECT *
> FROM T_unit_event_log AS A
> LEFT JOIN Myevents AS C
> ON A.event_log_no = C.event_log_no
> LEFT JOIN Myevents AS B
> ON A.event_ref_log_no = B.event_log_no
> WHERE C.event_log_no IS NULL
> AND B.event_log_no IS NOT NULL
> AND A.event_status = 1
> AND A.event_ref_log_no IS NOT NULL;
>
>
Hi Richard and thanks for the response. When I try the last two queries i get and error. I have listed
the results of explain on all three.
srm2=# explain
srm2-# INSERT INTO Myevents
srm2-# SELECT *
srm2-# FROM T_unit_event_log AS A
srm2-# WHERE A.event_status = 1
srm2-# AND A.event_ref_log_no IS NOT NULL
srm2-# AND A.event_log_no NOT IN ( SELECT event_log_no
srm2(# FROM Myevents)
srm2-# AND EXISTS ( SELECT B.event_log_no
srm2(# FROM Myevents AS B
srm2(# WHERE A.event_ref_log_no = B.event_log_no );
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------
Index Scan using indx_tuel_usn_ec_es on t_unit_event_log a (cost=31711.73..3607445990.61 rows=51844 width=146)
Index Cond: (event_status = 1)
Filter: ((event_ref_log_no IS NOT NULL) AND (subplan) AND (NOT (subplan)))
SubPlan
-> Materialize (cost=31711.73..42857.85 rows=830612 width=4)
-> Seq Scan on myevents (cost=0.00..28041.12 rows=830612 width=4)
-> Index Scan using indx1myevents on myevents b (cost=0.00..8.37 rows=1 width=4)
Index Cond: ($1 = event_log_no)
(8 rows)
srm2=#
srm2=#
srm2=# explain
srm2-# INSERT INTO Myevents
srm2-# SELECT *
srm2-# FROM T_unit_event_log AS A
srm2-# LEFT JOIN Myevents AS C
srm2-# ON A.event_log_no = C.event_log_no
srm2-# WHERE A.event_status = 1
srm2-# AND A.event_ref_log_no IS NOT NULL
srm2-# AND C.event_log_no IS NULL
srm2-# AND EXISTS ( SELECT B.event_log_no
srm2(# FROM Myevents AS B
srm2(# WHERE A.event_ref_log_no = B.event_log_no );
ERROR: INSERT has more expressions than target columns
srm2=#
srm2=# explain
srm2-# INSERT INTO Myevents
srm2-# SELECT *
srm2-# FROM T_unit_event_log AS A
srm2-# LEFT JOIN Myevents AS C
srm2-# ON A.event_log_no = C.event_log_no
srm2-# LEFT JOIN Myevents AS B
srm2-# ON A.event_ref_log_no = B.event_log_no
srm2-# WHERE C.event_log_no IS NULL
srm2-# AND B.event_log_no IS NOT NULL
srm2-# AND A.event_status = 1
srm2-# AND A.event_ref_log_no IS NOT NULL;
ERROR: INSERT has more expressions than target columns
I really appreciate your help.
Steve
pgsql-general by date: