Hamid Alavi wrote:
> 
> Hi List,
> 
> Is anybody have any idea for better performance for the following query:
> I just change the OR to UNION ALL
> Appreciate any idea.
> 
> SELECT a.evh_event_id
>         FROM event_history_evh a
>         WHERE
>         (a.evh_event_id = 2 AND
>          a.evh_created_date =
>          (SELECT max( b.evh_created_date )
>           FROM event_history_evh b
>           WHERE b.evh_session_id = 1785619526 AND
>           b.evh_task_list_id = a.evh_task_list_id AND
>           (sysdate - b.evh_created_date )*1440 < 5 AND
>           b.evh_task_list_id != 469602))
>         OR-------UNIN ALL
>         (a.evh_event_id = 2 AND
>          a.evh_created_date =
>          (SELECT max( c.evh_created_date )
>           FROM event_history_evh c
>           WHERE c.evh_session_id != 1785619526 AND
>           c.evh_task_list_id = a.evh_task_list_id AND
>           (sysdate - c.evh_created_date)*1440 < 5 AND
>           c.evh_task_list_id = 469602))
> 
> Hamid Alavi
> 
> Office          :  818-737-0526
> Cell phone  :  818-416-5095
> 

May I hope you were given this to tune after an especially hard week and
that you didn't write it yourself ?
It's beginning to be late here and I am beginning to feel sleepy, but I
think that
          (A = B and C != D) or (A != B and C = D)
can be simplified into 
           not (A = B and C = D)                
which makes the question 'OR or UNION ALL' a thing of the past.

Which brings us to :

 SELECT a.evh_event_id
         FROM event_history_evh a
         WHERE
         (a.evh_event_id = 2 AND
          a.evh_created_date =
          (SELECT max( b.evh_created_date )
           FROM event_history_evh b
           WHERE b.evh_task_list_id = a.evh_task_list_id AND
           (sysdate - b.evh_created_date )*1440 < 5 AND
           not (b.evh_session_id = 1785619526 and b.evh_task_list_id =
469602))

Now that it's a bit less hairy, it looks like it returns either '2'
(possibly several ones) or nothing.
Let's further our analysis, (sysdate - blahblah) looks ugly if you have
an index on evh_created_date (which would help with both the max()
function and the condition).
            (sysdate - b.evh_created_date) * 1440 < 5 would probably
better be written as
           sysdate - 5 / 1440 < b.evh_created_date 
(which I personnally understand better - created more than 5 minutes
ago).
What does remain ? Hmmm, your subquery is correlated, not too good if
evh_event_id is not very discriminant.
  What about :

 SELECT a.evh_event_id
 FROM event_history_evh a
 WHERE a.evh_event_id = 2 AND
       (a.evh_task_list_id, a.evh_created_date) in (SELECT 
b.evh_task_list,
                                                            max(
b.evh_created_date )
                                                    FROM
event_history_evh b
                                                    WHERE sysdate - 5 /
1440 < b.evh_created_date
                                                      AND not
(b.evh_session_id = 1785619526
                                                               and
b.evh_task_list_id = 469602)
                                                    group by
b.evh_task_list)
 ?

Either this or the correlated subquery,depending on volumes.

-- 
Regards,

Stephane Faroult
Oriole Software
-- 
Please see the official ORACLE-L FAQ: http://www.orafaq.net
-- 
Author: Stephane Faroult
  INET: [EMAIL PROTECTED]

Fat City Network Services    -- 858-538-5051 http://www.fatcity.com
San Diego, California        -- Mailing list and web hosting services
---------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: [EMAIL PROTECTED] (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB ORACLE-L
(or the name of mailing list you want to be removed from).  You may
also send the HELP command for other information (like subscribing).

Reply via email to