首页 > 代码库 > 10g full join 优化
10g full join 优化
今天一个女生咨询我报名学优化。聊着聊着就让我优化一个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 生效。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。