查询性能非常低+相关子查询

时间:2015-05-14 14:42:30

标签: oracle11g

查询的目的是获取预订房间状态为3或预留30至45分钟状态2或1无保留状态1.预订房间位于RESEENH表中,每个预订位于ORD_NOARCHIVE表中,该表具有开始时间和结束时间保留。因此,对于每个预订房间,该查询检查当前时间是否有预订,还检查会议室的父母和孩子。如果孩子被保留,那么父母就会被封锁。 获取前50条记录需要10秒钟。

with cte as 
(
 SELECT DISTINCT R.syscode, 
                R.behcode,                
                R.syscode AS FK_RESERVATIONUNIT, ( 
                CASE 
                                WHEN R.TYPE = 3 THEN '1' 
                                WHEN R.TYPE = 1 THEN '2' 
                                ELSE NULL 
                END )                               AS LOCATION_TYPE, 
                R.sysobjalg                         AS FK_PROPERTY, 

                MP.syscode                          AS FK_MEASUREMENTPOINT, 
                MP.fk_plc_occupancy_state           AS FK_PLC_OCCUPANCY_STATE, 
                F.syscode                           AS FK_FLOOR,
                R.transitiontime,
                r.type,
                r.is_compoundreservationunit,
                r.is_archived,
                MP.fk_person,
                os.transitionperiod
FROM            reseenh R 
--left outer join ordtrantbl RSS 
--ON              RSS.reservationunisyscode = R.syscode 
left outer join objond F 
ON              F.syscode = R.fk_floor 
left outer join pln_measurementpoint MP 
ON              MP.fk_reservationunit = R.syscode 
AND             MP.is_primary_measurement_point = 'T',
pln_ordersetting os 

)
select cte.syscode,cte.behcode,cte.FK_RESERVATIONUNIT,
 (CASE 
                                WHEN O.begindatetime_user IS NULL THEN '1'                                                                 --GREEN 
                                WHEN O.begindatetime_user - (Nvl(cte.transitiontime, ( cte.transitionperiod ))/1440 ) > current_date THEN '2'  -- ORANGE 
                                WHEN O.begindatetime_user + (Nvl(cte.transitiontime, ( cte.transitionperiod )) /1440 ) > current_date THEN '3' -- RED 
                                ELSE '3' 
                END )     AS LOCAVAILABILITY_STATUS_CODE, 
                cte.LOCATION_TYPE,                
                cte.FK_PROPERTY,
                 Coalesce(O.sysmelder, cte.fk_person) AS FK_PERSON, 
                O.syscode                           AS FK_ORDER, 
                O.ref_bostate_userdefined           AS FK_ORDER_STATE_USER, 
                O.fk_bostate                        AS FK_ORDER_STATE_SYSTEM,
                FK_MEASUREMENTPOINT,FK_PLC_OCCUPANCY_STATE,FK_FLOOR
from cte left outer join ord_noarchive O on O.syscode in 
( SELECT MAX(ord.syscode) KEEP (DENSE_RANK FIRST ORDER BY ord.begindatetime_user) OVER (PARTITION BY ord.sysreseenh )
                       FROM   ord_noarchive ORD 


                       WHERE  ( ( ( 
                                                   current_date >= ( ORD.begindatetime_user - ( Nvl(cte.transitiontime, ( cte.transitionperiod ))/1440) )
                                            AND    ( 
                                                          current_date - ( Nvl(cte.transitiontime, (cte.transitionperiod )) / 1440 ) ) <=ORD.enddatetime_user )
                                     OR     ( ( 
                                                          current_date + ( ( 
                                                          CASE 
                                                                 WHEN ( 
                                                                               cte.TYPE = 1 ) THEN 30
                                                                 ELSE 45 
                                                          END ) / 1440 ) ) >= ( ORD.begindatetime_user - (Nvl(cte.transitiontime, ( cte.transitionperiod))/1440 ) )
                                            AND    ( 
                                                          current_date - ( Nvl(cte.transitiontime, ( cte.transitionperiod )) / 1440 ) ) < ORD.enddatetime_user ) )
                              AND    ORD.sysreseenh IN 
                                     ( 
                                            SELECT fk_reservationunit_parent 
                                            FROM   pln_reservationunit_rut 
                                            WHERE  fk_reservationunit_child IN 
                                                   ( 
                                                          SELECT fk_reservationunit_child 
                                                          FROM   pln_reservationunit_rut 
                                                          WHERE  cte.is_compoundreservationunit = 'T'
                                                          AND    fk_reservationunit_parent = cte.syscode)
                                            UNION 
                                            SELECT cte.syscode 
                                            FROM   dual 
                                            UNION 
                                            SELECT 
                                                   CASE 
                                                          WHEN cte.is_compoundreservationunit = 'T' THEN fk_reservationunit_child
                                                          ELSE fk_reservationunit_parent 
                                                   END 
                                            FROM   pln_reservationunit_rut 
                                            WHERE  ( 
                                                          cte.is_compoundreservationunit = 'T' 
                                                   AND    fk_reservationunit_parent = cte.syscode )
                                            OR     ( 
                                                          cte.is_compoundreservationunit = 'F' 
                                                   AND    fk_reservationunit_child = cte.syscode ))
                              AND    ORD.fk_bostate IN 
                                     ( 
                                            SELECT syscode 
                                            FROM   pln_bostate 
                                            WHERE  pnname IN ( 'Requested', 
                                                              'Made', 
                                                              'AdministrativelyCompleted' ) 
                                            AND    fk_bodefinition = ref_bodefinition) 

                              AND    ORD.sysreseenh = O.sysreseenh                                
                              ))
 WHERE           cte.is_archived = 'F' 
AND             cte.TYPE IN ( 1, 
                           3 )  
                       AND             cte.fk_floor=495  

1 个答案:

答案 0 :(得分:0)

没时间分析一个非常复杂的查询的细节,但我的总体感觉是你试图一次做太多事情。分开任务。在一个查询中检查房间可用性,并在单独的查询中检查子/父事物。

此外,您可以分析查询的执行计划,并查看它对其造成的影响。我怀疑(再次没有时间真正尝试理解你的查询)是在某些时候,任务的混合正在转化为多对多的关系,你有一个中间结果,这是一些行之间的行的交叉产品查询中的表格。