10g full join 最佳化

來源:互聯網
上載者:User

今天一個女生諮詢我報名學最佳化。聊著聊著就讓我最佳化一個sql,貼給大家看一下

select (case         when grouping(allwo.workshop_code) = 1 then          ''         else          nvl(max(allwo.workshop_code), '未維護車間')       end) workshop_code,       DECODE(TO_NUMBER(substr(Item_code,                               4,                               INSTR(Item_code, 'M', 1, 2) - 4)) / 10,              NULL,              '合計',              TO_NUMBER(substr(Item_code, 4, INSTR(Item_code, 'M', 1, 2) - 4)) / 10 || 'M') xiangsu,       (case         when grouping(item_code) = 1 then          ''         else          max(part_spec)       end) part_spec,       (case         when grouping(item_code) = 1 then          ''         else          max(type)       end) type,       nvl(wo_code, '') wo_code,       sum(qty) qty,       sum(UsedQty) qx,       sum(db) db,       sum(wb) wb,       sum(HM) HM,       sum(成品站) 成品站,       sum(烘烤) 烘烤,       sum(十級產出) 十級產出,       sum(分粒接收) 分粒接收,       sum(分粒修邊) 分粒修邊,       sum(焊接) 焊接,       sum(噴碼打標) 噴碼打標,       sum(撕膜) 撕膜,       sum(調焦) 調焦,       sum(點膠) 點膠,       sum(點膠全檢) 點膠全檢,       sum(功測一) 功測一,       sum(功測接收修複) 功測接收修複,       sum(功測二) 功測二,       sum(QC功測) QC功測,       sum(遠焦燒錄) 遠焦燒錄,       sum(近焦燒錄) 近焦燒錄,       sum(OTP燒錄) OTP燒錄,       sum(OTP檢測) OTP檢測,       sum(QCOTP燒錄) QCOTP燒錄,       sum(背膠) 背膠,       sum(外觀) 外觀,       sum(OS測試) OS測試,       sum(CCD檢驗) CCD檢驗,       sum(貼膜) 貼膜,       sum(封裝) 封裝,       sum(封裝入庫) 封裝入庫,       sum(修複接收) 修複接收,       sum(修複維修) 修複維修,       sum(髒點測試) 髒點測試,       sum(修複焊接) 修複焊接,       sum(修複修邊) 修複修邊,       sum(修複調焦) 修複調焦,       sum(修複功能測試) 修複功能測試,       sum(修複轉出) 修複轉出  from (select COALESCE(wocode,                        gxcl.wo_code,                        bz.wo_code,                        xiufujieshou.wo_code) wocode,               nvl(UsedQty, 0) UsedQty,               nvl(db, 0) db,               nvl(wb, 0) wb,               nvl(成品站, 0) 成品站,               nvl(HM, 0) HM,               nvl(烘烤, 0) 烘烤,               nvl(十級產出, 0) 十級產出,               nvl(分粒接收, 0) 分粒接收,               nvl(分粒修邊, 0) 分粒修邊,               nvl(焊接, 0) 焊接,               nvl(噴碼打標, 0) 噴碼打標,               nvl(撕膜, 0) 撕膜,               nvl(調焦, 0) 調焦,               nvl(點膠, 0) 點膠,               nvl(點膠全檢, 0) 點膠全檢,               nvl(功測一, 0) 功測一,               nvl(功測接收修複, 0) 功測接收修複,               nvl(功測二, 0) 功測二,               nvl(QC功測, 0) QC功測,               nvl(遠焦燒錄, 0) 遠焦燒錄,               nvl(近焦燒錄, 0) 近焦燒錄,               nvl(OTP燒錄, 0) OTP燒錄,               nvl(OTP檢測, 0) OTP檢測,               nvl(QCOTP燒錄, 0) QCOTP燒錄,               nvl(背膠, 0) 背膠,               nvl(外觀, 0) 外觀,               nvl(OS測試, 0) OS測試,               nvl(CCD檢驗, 0) CCD檢驗,               nvl(貼膜, 0) 貼膜,               nvl(修複接收, 0) 修複接收,               nvl(修複維修, 0) 修複維修,               nvl(髒點測試, 0) 髒點測試,               nvl(修複焊接, 0) 修複焊接,               nvl(修複修邊, 0) 修複修邊,               nvl(修複調焦, 0) 修複調焦,               nvl(修複功能測試, 0) 修複功能測試,               nvl(修複轉出, 0) 修複轉出,               nvl(封裝入庫, 0) 封裝入庫,               nvl(封裝, 0) 封裝          from (SELECT WO_CODE AS WoCode, sum(USED_QTY) AS UsedQty                  FROM T_SN2UPN                 where (mat_code like 'MFY%' OR mat_code like 'EMBY%')                   and MDATE >=                       to_date('2014-04-27 08:30', 'yyyy-mm-dd hh24:mi:ss')                   AND MDATE <=                       to_date('2014-04-28 08:30', 'yyyy-mm-dd hh24:mi:ss')                   and SUBSTR(TO_CHAR(MDATE + 30 / 1440, 'YYYYMMDDHH24MISS'),                              9,                              2) >= 9                   AND SUBSTR(TO_CHAR(MDATE + 30 / 1440, 'YYYYMMDDHH24MISS'),                              9,                              2) < 21                 group by Wo_Code) qx          full join (select A.item_code,                           A.wo_code,                           C.PIXEL,                           SUM(case                                 when a.op_code = 'DB' THEN                                  OK_QTY                                 ELSE                                  0                               END) DB,                           SUM(case                                 when a.op_code = 'WB後全檢' THEN                                  OK_QTY                                 ELSE                                  0                               END) WB,                           SUM(case                                 when a.op_code in                                      ('半成品組裝', '組裝LENS', 'VCM封合') THEN                                  OK_QTY                                 ELSE                                  0                               END) 成品站,                           SUM(case                                 when a.op_code = 'H/M' THEN                                  OK_QTY                                 ELSE                                  0                               END) HM,                           SUM(case                                 when a.op_code = '烘烤' THEN                                  OK_QTY                                 ELSE                                  0                               END) 烘烤,                           SUM(case                                 when a.op_code = '十級轉出' THEN                                  OK_QTY                                 ELSE                                  0                               END) 十級產出,                           SUM(case                                 when a.op_code = '分粒接收' THEN                                  OK_QTY                                 ELSE                                  0                               END) 分粒接收,                           SUM(case                                 when a.op_code = '修邊' THEN                                  OK_QTY                                 ELSE                                  0                               END) 分粒修邊,                           SUM(case                                 when a.op_code = '馬達焊接' THEN                                  OK_QTY                                 ELSE                                  0                               END) 焊接,                           SUM(case                                 when a.op_code = '打標' THEN                                  OK_QTY                                 ELSE                                  0                               END) 噴碼打標,                           SUM(case                                 when a.op_code = '撕膜' THEN                                  OK_QTY                                 ELSE                                  0                               END) 撕膜,                           SUM(case                                 when a.op_code = '調焦' THEN                                  OK_QTY                                 ELSE                                  0                               END) 調焦,                           SUM(case                                 when a.op_code = '點螺紋膠及UV固化' THEN                                  OK_QTY                                 ELSE                                  0                               END) 點膠,                           SUM(case                                 when a.op_code = '點UV膠後全檢膠量' THEN                                  OK_QTY                                 ELSE                                  0                               END) 點膠全檢,                           SUM(case                                 when a.op_code = '功能測試' THEN                                  OK_QTY                                 ELSE                                  0                               END) 功測一,                           SUM(case                                 when a.op_code = '功能測試接收(修複)' THEN                                  OK_QTY                                 ELSE                                  0                               END) 功測接收修複,                           SUM(case                                 when a.op_code = '功能測試02' THEN                                  OK_QTY                                 ELSE                                  0                               END) 功測二,                           SUM(case                                 when a.op_code = 'QC功能檢' THEN                                  OK_QTY                                 ELSE                                  0                               END) QC功測,                           SUM(case                                 when a.op_code = '遠焦燒錄' THEN                                  OK_QTY                                 ELSE                                  0                               END) 遠焦燒錄,                           SUM(case                                 when a.op_code = '近焦燒錄' THEN                                  OK_QTY                                 ELSE                                  0                               END) 近焦燒錄,                           SUM(case                                 when a.op_code = 'OTP燒錄' THEN                                  OK_QTY                                 ELSE                                  0                               END) OTP燒錄,                           SUM(case                                 when a.op_code = 'OTP檢測' THEN                                  OK_QTY                                 ELSE                                  0                               END) OTP檢測,                           SUM(case                                 when a.op_code = 'QC OTP檢測' THEN                                  OK_QTY                                 ELSE                                  0                               END) QCOTP燒錄,                           SUM(case                                 when a.op_code = '貼背膠' THEN                                  OK_QTY                                 ELSE                                  0                               END) 背膠,                           SUM(case                                 when a.op_code = '外觀檢查' THEN                                  OK_QTY                                 ELSE                                  0                               END) 外觀,                           SUM(case                                 when a.op_code = 'O/S測試' THEN                                  OK_QTY                                 ELSE                                  0                               END) OS測試,                           SUM(case                                 when a.op_code = 'CCD檢驗' THEN                                  OK_QTY                                 ELSE                                  0                               END) CCD檢驗,                           SUM(case                                 when a.op_code = '貼膜' THEN                                  OK_QTY                                 ELSE                                  0                               END) 貼膜,                           SUM(case                                 when a.op_code = '修複維修' THEN                                  OK_QTY                                 ELSE                                  0                               END) 修複維修,                           SUM(case                                 when a.op_code = '髒點測試' THEN                                  OK_QTY                                 ELSE                                  0                               END) 髒點測試,                           SUM(case                                 when a.op_code = '修複焊接' THEN                                  OK_QTY                                 ELSE                                  0                               END) 修複焊接,                           SUM(case                                 when a.op_code = '修複修邊' THEN                                  OK_QTY                                 ELSE                                  0                               END) 修複修邊,                           SUM(case                                 when a.op_code = '修複調焦' THEN                                  OK_QTY                                 ELSE                                  0                               END) 修複調焦,                           SUM(case                                 when a.op_code = '修複功能測試' THEN                                  OK_QTY                                 ELSE                                  0                               END) 修複功能測試,                           SUM(case                                 when a.op_code = '修複功能測試' THEN                                  OK_QTY                                 ELSE                                  0                               END) 修複轉出                      from t_resume a, i_material c                     WHERE a.item_code = c.part_code                       AND (a.rcard, a.op_code, a.actionseq) in                           (select rcard, op_code, max(actionseq) actionseq                              from t_resume                             where MDATE >=                                   to_date('2014-04-27 08:30',                                           'yyyy-mm-dd hh24:mi:ss')                               AND MDATE <=                                   to_date('2014-04-28 08:30',                                           'yyyy-mm-dd hh24:mi:ss')                             group by rcard, op_code)                       AND A.WO_CODE = 'MN1-14040158'                                         GROUP BY A.ITEM_CODE, A.WO_CODE, C.PIXEL                                        ) gxcl            on qx.WoCode = gxcl.wo_code                  full join (select substr(rcard, 1, 12) wo_code,                           sum(case                                 when (IS_PACKING = 1 and                                      a.PACKING_DATE >=                                      to_date('2014-04-27 08:30',                                               'yyyy-mm-dd hh24:mi:ss') AND                                      a.PACKING_DATE <=                                      to_date('2014-04-28 08:30',                                               'yyyy-mm-dd hh24:mi:ss')) and                                      SUBSTR(TO_CHAR(a.PACKING_DATE + 30 / 1440,                                                     'YYYYMMDDHH24MISS'),                                             9,                                             2) >= 9 AND                                      SUBSTR(TO_CHAR(PACKING_DATE + 30 / 1440,                                                     'YYYYMMDDHH24MISS'),                                             9,                                             2) < 21 then                                  used_qty                                 else                                  0                               end) 封裝,                           sum(case                                 when (IS_BZTOSTOCK = 1 and                                      a.BZTOSTOCK_DATE >=                                      to_date('2014-04-27 08:30',                                               'yyyy-mm-dd hh24:mi:ss') AND                                      a.BZTOSTOCK_DATE <=                                      to_date('2014-04-28 08:30',                                               'yyyy-mm-dd hh24:mi:ss')) and                                      SUBSTR(TO_CHAR(a.BZTOSTOCK_DATE + 30 / 1440,                                                     'YYYYMMDDHH24MISS'),                                             9,                                             2) >= 9 AND                                      SUBSTR(TO_CHAR(BZTOSTOCK_DATE + 30 / 1440,                                                     'YYYYMMDDHH24MISS'),                                             9,                                             2) < 21 then                                  used_qty                                 else                                  0                               end) 封裝入庫                      from (select *                              from T_CARTON                             where status IS NULL                               and workshop_code = '生產二區') a                     inner join t_carton2SN b                        on a.carton_no = b.carton_no                       AND ((a.BZTOSTOCK_DATE >=                           to_date('2014-04-27 08:30',                                     'yyyy-mm-dd hh24:mi:ss') AND                           a.BZTOSTOCK_DATE <=                           to_date('2014-04-28 08:30',                                     'yyyy-mm-dd hh24:mi:ss')) OR                           (a.PACKING_DATE >=                           to_date('2014-04-27 08:30',                                     'yyyy-mm-dd hh24:mi:ss') AND                           a.PACKING_DATE <=                           to_date('2014-04-28 08:30',                                     'yyyy-mm-dd hh24:mi:ss')))                     group by substr(rcard, 1, 12)) bz            on gxcl.wo_code = bz.wo_code                  full join                 (select wo_code, sum(ng_qty) 修複接收           from QTMR01          where MDATE >=                to_date('2014-04-27 08:30', 'yyyy-mm-dd hh24:mi:ss')            AND MDATE <=                to_date('2014-04-28 08:30', 'yyyy-mm-dd hh24:mi:ss')            and SUBSTR(TO_CHAR(MDATE + 30 / 1440, 'YYYYMMDDHH24MISS'), 9, 2) >= 9            AND SUBSTR(TO_CHAR(MDATE + 30 / 1440, 'YYYYMMDDHH24MISS'), 9, 2) < 21          group by wo_code) xiufujieshou            on xiufujieshou.wo_code = gxcl.wo_code) jieguo inner join i_wo allwo    on allwo.wo_code = jieguo.wocode inner join i_material M    on m.part_code = allwo.item_code where 1 = 1   and allwo.workshop_code = '生產二區' group by rollup(item_code, allwo.workshop_code, wo_code)


該sql是 olap 的, 在oracle10g 上面跑。跑一次要33秒鐘,一般olap報表,最好的客戶體驗要在5秒以內。

大家注意看,sql裡面有full join,在oracle10g裡面,full join預設會掃描2次,一次left join 一次right join 然後union all. 這樣肯定慢了。在11g 只掃描1次。

10g 裡面可以用 一個hint  /*+ NATIVE_FULL_OUTER_JOIN */ ,讓他們掃描1次

加了hint之後,SQL 3秒能出結果,她還問能否進一步最佳化,因為要講課了,8點半講課,沒啥時間,明天幫忙看吧。

注意,這個hint別放在 第一個select 後面,這樣是沒用的。要放在 from (select /*+ NATIVE_FULL_OUTER_JOIN */  COALESCE(wocode,

也就是說要離full join 最近的一個 select 。至於為什麼,請自己 google query block 關鍵字, hint一般只在 query block 生效。


 




相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.