一个很长的查询调优

时间:2016-03-29 13:10:30

标签: sql oracle query-optimization oracle-ebs

我有以下查询,在此查询中,我选择了ebs表,其中包含一个自定义表,该表具有header_id并在自定义表XXREPORT_L1_TBL中填充数据。

我想调整此查询。

[update]对查询进行了更改:

  1. 将查询拆分为3个不同的插入语句
  2. 删除了对值进行排队查询的列
  3. 在这些列的末尾添加了更新声明。

    insert into XX.XXREPORT_L1_TBL ( ORDER_NUMBER 
                                            , LINE_NUMBER
                                            , UOM
                                            , CUSTOMER_LENGTH
                                            , THEORETICAL_WEIGHT
                                            , FINISH
                                            , ORDER_QTY_PCS
                                            , ORDER_QTY_KGS
                                            , SALES_VALUE
                                            , TOTAL_VALUE
                                            , ORDERED_QUANTITY 
                                            , WIP_ENTITY_ID 
                                            , JOB_NAME
                                            , JOB_TYPE
                                            , JOB_STATUS 
                                            , JOB_RELEASED_DATE 
                                            , DATE_COMPLETED
                                            , DATE_CLOSED
                                            , JOB_CARD_QTY 
                                            , ALLOY 
                                            , PROFILE
                                            , PROD_QTY_KGS 
                                            , COST_KGS_THEORY 
                                            , COST_KGS_ACTUAL
        )
    
    SELECT 
     ---- Sales Order
       xx.order_number
       ,xx.line_number 
       ,xx.UOM,
       xx.customer_length,
       xx.theoretical_weight,
       xx.finish,
       xx.order_qty_pcs, 
       xx.order_qty_kgs,      
       xx.sales_value, -- total value / total kgs
       xx.total_value, -- line total
       xx.ordered_quantity,
     -- Production
       xx.wip_entity_id,
       xx.job_name,
       ( select case when a.inventory_item_id = 5716770 and a.job_type='NOT CHILD' then 'PARENT' 
                when a.job_type='CHILD' and a.inventory_item_id is null then 'CHILD' 
                when a.job_type='NOT CHILD' and a.inventory_item_id is NOT null then 'NOT CHILD' END JOB_TYPE 
         from ( select  disc2.wip_entity_id as wip_entity_id,      decode      (      nvl(disc2.attribute9,-1) , -1,'NOT CHILD', 'CHILD') job_type,      oel.inventory_item_id
                      from APPS.wip_discrete_jobs disc2,      APPS.oe_order_lines_all oel
                      where oel.line_id(+) = disc2.source_line_id
               )a
         where a.wip_entity_id = xx.wip_entity_id
       ) job_type, 
       ( select decode ( xx.status_type, 6, 'Open',
                                       3, 'Open',
                                       4,      'Completed',                                          
                                        LU1.MEANING )
                from APPS.FND_LOOKUP_VALUES LU1 
                where  LU1.LOOKUP_TYPE = 'WIP_JOB_STATUS'
                AND LU1.LOOKUP_CODE = xx.STATUS_TYPE
       ) job_status,      
       xx.job_released_date,
       xx.date_completed, 
       xx.date_closed
       ,xx.net_quantity as job_card_qty
       ,xx.alloy
       ,xx.profile
       ,xx.prod_qty_kgs      
         -- Theoretical Order cost  
       ,xx.cost_kgs_theory
         -- Actual Order cost      
       ,xx.cost_kgs_actual
         from (      
          select a.*
        -- Theoretical Order cost
                , DECODE (a.qty_completed * a.customer_length * a.theoretical_weight,0,0,
                    a.TOT_THEORY_COST_RELIEVED/(a.qty_completed * a.customer_length * a.theoretical_weight) ) as cost_kgs_theory 
        -- Actual Order cost
                , DECODE ( a.qty_completed * a.customer_length * a.theoretical_weight, 0, 0,
                    a.TOT_ACTUAL_COST_INCURRED/(a.qty_completed * a.customer_length * a.theoretical_weight )) as cost_kgs_actual
                from ( 
    
      select 
     -- Normal orders, INTERNAL Orders, Crimped Profile (parent jobs)     
       -- Sales Order      
            oeh.order_number as order_number
            ,oel.line_number
            ,oel.pricing_quantity_uom as UOM
            ,oel.attribute1 as customer_length
            ,oel.attribute6 as theoretical_weight
            ,oel.attribute5 as finish
            ,oel.attribute18 as order_qty_pcs
            ,oel.attribute7 as order_qty_kgs
            ,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
            ,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
            ,oel.ordered_quantity ordered_quantity
     -- Production                
            , tbl0.qty_completed as qty_completed
            ,disc.wip_entity_id as wip_entity_id
            ,( select wip_entity_name from APPS.wip_entities ent
                where ent.wip_entity_id = disc.wip_entity_id) job_name
            ,disc.status_type
            ,disc.date_released as job_released_date
            , DECODE ( disc.date_completed, NULL, disc.date_completed,
            -- my day Definition
            to_date(to_char(to_date(TO_CHAR(disc.date_completed-     interval      '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'),      'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY      HH24:MI:SS'))      as      date_completed
            , DECODE ( disc.date_closed, NULL, disc.date_closed,
            to_date(to_char(to_date(TO_CHAR(disc.date_closed-     interval      '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'),      'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'))      as      date_closed
            , disc.net_quantity
       , ( select opr2.quantity_completed
             from APPS.wip_operations opr2
        where opr2.wip_entity_id = disc.wip_entity_id
        and opr2.operation_seq_num =       (select max(opr.operation_seq_num)
                                          from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
                                          where opr.wip_entity_id = disc2.wip_entity_id 
                                          and disc2.wip_entity_id =  disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs
            ,oel.attribute4 as alloy
            ,oel.attribute2 as profile
    
     -- Theoretical Order cost
              ,tbl0.TOT_THEORY_COST_RELIEVED
     -- Actual Order cost 
              ,tbl0.TOT_ACTUAL_COST_INCURRED
     from XX.XXREPORT_Lzero_TBL tbl0
     join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id 
     join APPS.oe_order_lines_all oel on   oeh.org_id = oel.org_id and     oeh.header_id = oel.header_id
     join APPS.xx_assemblies asm on oel.line_id = asm.line_id
     join APPS.wip_discrete_jobs disc on disc.primary_item_id = asm.inventory_item_id
       where  oel.link_to_line_id is null
    
     union
     -- Crimped Child Jobs
      select 
     -- Sales Order      
            oeh.order_number as order_number
            ,oel.line_number
            ,oel.pricing_quantity_uom as UOM
            ,oel.attribute1 as customer_length
            ,oel.attribute6 as theoretical_weight
            ,oel.attribute5 as finish
            ,oel.attribute18 as order_qty_pcs
            ,oel.attribute7 as order_qty_kgs
            ,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
            ,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
            ,oel.ordered_quantity ordered_quantity
     -- Production
            , tbl0.qty_completed as qty_completed
            ,child_jobs.wip_entity_id as wip_entity_id
            ,( select wip_entity_name from APPS.wip_entities ent
                where ent.wip_entity_id = child_jobs.wip_entity_id)          job_name
            ,disc.status_type
            ,disc.date_released as job_released_date
            , DECODE ( disc.date_completed, NULL, disc.date_completed,
            to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval      '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'),      'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as      date_completed
            , DECODE ( disc.date_closed, NULL, disc.date_closed,
            to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval      '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'),      'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as      date_closed
            , disc.net_quantity
            , ( select opr2.quantity_completed
                  from APPS.wip_operations opr2
                  where opr2.wip_entity_id = disc.wip_entity_id
                  and opr2.operation_seq_num =       (select          max(opr.operation_seq_num)
                                                    from     APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
                                                    where opr.wip_entity_id = disc2.wip_entity_id 
                                                    and disc.wip_entity_id =  disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs                
            ,oel.attribute4 as alloy
            ,oel.attribute2 as profile
     -- Theoretical Order cost
              ,tbl0.TOT_THEORY_COST_RELIEVED
     -- Actual Order cost 
              ,tbl0.TOT_ACTUAL_COST_INCURRED     
    from XX.XXREPORT_Lzero_TBL tbl0
     join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
     join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and     oeh.header_id = oel.header_id
     join APPS.xx_assemblies asm on oel.line_id = asm.line_id
     join APPS.wip_discrete_jobs disc on disc.primary_item_id =     asm.inventory_item_id 
     join ( select wdj2.source_line_id, wdj2.attribute9 child_wip, wdj2.wip_entity_id, wdj2.status_type status_type
        from APPS.wip_discrete_jobs wdj2
        where attribute9 IS NOT NULL ) child_jobs on      child_jobs.child_wip = to_char(disc.wip_entity_id)
     where oel.link_to_line_id is null
    
      union
      -- Orders with star (*) items need to pick profile and customer      length etc from ego_configured_pr_agv view 
      select 
     -- Sales Order      
            oeh.order_number as order_number
            ,oel.line_number
            ,oel.pricing_quantity_uom as UOM
            ,to_char(agv.gx_cp_length) as customer_length
            ,to_char(agv.gx_cp_th_weight) as theoretical_weight
            ,agv.gx_cp_surfacetreatment as finish
            ,oel.attribute18 as order_qty_pcs
            , to_char(agv.gx_cp_th_weight * agv.gx_cp_length *          oel.ordered_quantity) as order_qty_kgs
            ,XX.xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
            ,XX.xx_om.GetHeaderUnitSellingPrice(oeh.header_id)      total_value
            ,oel.ordered_quantity ordered_quantity
     -- Production                
            , tbl0.qty_completed as qty_completed
            ,disc.wip_entity_id as wip_entity_id
            ,( select wip_entity_name from APPS.wip_entities ent
                where ent.wip_entity_id = disc.wip_entity_id) job_name
            ,disc.status_type
            ,disc.date_released as job_released_date
            , DECODE ( disc.date_completed, NULL, disc.date_completed,
            to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval      '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'),      'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as      date_completed
            , DECODE ( disc.date_closed, NULL, disc.date_closed,
            to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval      '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'),      'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as      date_closed
            , disc.net_quantity
       , ( select opr2.quantity_completed
        from APPS.wip_operations opr2
        where opr2.wip_entity_id = disc.wip_entity_id
        and opr2.operation_seq_num =       (select      max(opr.operation_seq_num)
                                          from APPS.wip_operations opr,      APPS.wip_discrete_jobs disc2
                                          where opr.wip_entity_id =      disc2.wip_entity_id 
                                          and disc2.wip_entity_id =       disc.wip_entity_id))* agv.gx_cp_length * agv.gx_cp_th_weight as      prod_qty_kgs
            ,gx_cp_alloy as alloy
            ,gx_cp_profile_id as profile
     -- Theoretical Order cost
              ,tbl0.TOT_THEORY_COST_RELIEVED
     -- Actual Order cost 
              ,tbl0.TOT_ACTUAL_COST_INCURRED
    
     from XX.XXREPORT_Lzero_TBL tbl0
     join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
     join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and          oeh.header_id = oel.header_id
     join APPS.wip_discrete_jobs disc on oel.line_id =      disc.source_line_id
     join APPS.ego_gx_configured_pr_agv agv on agv.inventory_item_id=      oel.inventory_item_id
       where oel.link_to_line_id is null
            )a 
            ) xx;
    

1 个答案:

答案 0 :(得分:1)

调整此查询几乎肯定没有简短的解决方案。这里的问题是它的大小和复杂性。缺乏表现仅仅是一种结果。

作为第一步,我会考虑从键盘上休息一下。拿一支笔和纸,用简单的英语(或您喜欢的“人类”语言)通过此查询从数据库中写下您想要回答的问题。那么问问自己你真的需要回答哪些列/变量/属性来回答这些问题?也要写下来。

现在,您真的需要所有这些列,嵌套连接,选择等来生成这些变量吗?也许,但可能不是。这里的关键点是只关注你需要的数据/信息(YAGNI),并从那里绘制出一张图片,显示你需要产生回答你问题的信息的裸体关系。换句话说,从外部工作,而不是相反。

我意识到这听起来有点抽象和模糊,但重点是保持清晰简单的代码始终是一场持续的斗争。密切关注手头的目标将有助于保持你的头脑。

最后,一些更具体的想法一目了然:

  • 你真的需要那个联盟吗?如果可以的话,尽量不要这样做。
  • 嵌套糟透了。嵌套嵌套特别糟糕。尽可能保持平稳和实用。
  • 将其拆分为独立的小型查询是否可行或可行?
  • 为变量使用更具描述性的名称,明智地添加注释。
  • 学习并掌握SQL EXPLAIN命令。