• Oracle SQl优化总结


        对数据库技术的热爱是我唯一的安慰,毕竟这是自己喜欢的事情,还可以做下去。

        因为客户项目的需要,我又开始接触Oracle,大部分工作在工作流的优化和业务数据的排查上。为了更好的做这份工作,我有参考过oracle达人,Oracle.10g性能分析与优化思路,基于海量数据的数据库设计与优化等书籍,以及案例学习SQL优化的视频等。基本上我工作中接触的主要是Oracle SQl的优化,基于长时间做SQL优化工作,现对Oracle的SQL优化做一下自己的总结。

        已知,Oracle10G以后执行计划使用基于CBO: Cost-Based Optimization 基于代价的优化器。当然在oracle 10G运行的SQL执行计划肯定是系统以为的最优了,很多时候没有办法看出优化点,不管怎么改都不比原来的性能好。怎么办呢?我每次还是傻傻的看着执行计划研究半天,很多时候这是不需要的,或者是有更快的方法发现问题所在。

        当然,每个人习惯和优化思路都会有不同,优化问题的处理也会不同。基于最近我优化一个程序的四个修改点,程序有原来的7个小时左右缩短为1小时左右执行。总结下我的步骤和优化思路。

    1、直接观察表的数据量和表结构属性,不拘泥考虑执行计划的最优  (大数据表利用全表 Hash关联)

    简写原SQL:

    SELECT count(1) 
    FROM Z_MID_R3_BOM_ORG1 A
    WHERE trunc(a.DATUV)<=trunc(sysdate) and trunc(a.DATUB) >=trunc(sysdate)
    and exists (select 1 from rpt_fp_shortage_order c
    where instr(a.name,c.mtm)>0
    and a.werks= c.siteid)
    and exists (select 1 from mst_bomcomponentsalt b
    where INSTR(b.bomid,a.name)>0
    and a.idnrk=b.ALTERNATEITEM
    and a.werks=b.siteid);

    实际这条SQL的结果集大概在20多万条记录,结果集插入另外一张表。Z_MID_R3_BOM_ORG1表和MST_BOMCOMPONENTSALT 表的数据量在一百多万条记录,RPT_FP_SHORTAGE_ORDER 表的数据量在7000条左右。

    执行计划:

    SELECT STATEMENT  ALL_ROWSCost: 2,595  Bytes: 64  Cardinality: 1              
        5 FILTER          
            1 TABLE ACCESS FULL TABLE PRDABPPCDB.Z_MID_R3_BOM_ORG1 Cost: 1,198  Bytes: 55,616  Cardinality: 869      
            2 TABLE ACCESS FULL TABLE PRDABPPCDB.RPT_FP_SHORTAGE_ORDER Cost: 3  Bytes: 17  Cardinality: 1      
            4 TABLE ACCESS BY INDEX ROWID TABLE PRDABPPCDB.MST_BOMCOMPONENTSALT Cost: 91  Bytes: 48  Cardinality: 1      
                3 INDEX FAST FULL SCAN INDEX PRDABPPCDB.S9525213703_2688 Cost: 3  Cardinality: 195  
    由执行计划可知,PRDABPPCDB.MST_BOMCOMPONENTSALT 表使用快速索引扫描,看似已经是最优。能利用的表属性索引已经使用了。但是近20万条记录,观察日志发现这一步骤插入的时间用了快2个小时。利用全表 Hash关联,修改后插入表的时间约为3分钟内执行完。

    修改后的SQL:

    SELECT count(1) 
    FROM Z_MID_R3_BOM_ORG1 A
    WHERE trunc(a.DATUV)<=trunc(sysdate) and trunc(a.DATUB) >=trunc(sysdate)
    and exists (select 1 from rpt_fp_shortage_order c 
    where instr(a.name,c.mtm)>0
    and a.werks= c.siteid)
    and exists (select /*+FULL(B)*/ 1 from mst_bomcomponentsalt b
    where INSTR(b.bomid,a.name)>0
    and a.idnrk=b.ALTERNATEITEM
    and a.werks=b.siteid);

    修改后的执行计划:
    Plan
    SELECT STATEMENT  ALL_ROWSCost: 8,748  Bytes: 111  Cardinality: 1                  
        6 SORT AGGREGATE  Bytes: 111  Cardinality: 1              
            5 FILTER          
                3 HASH JOIN SEMI  Cost: 8,676  Bytes: 111  Cardinality: 1      
                    1 TABLE ACCESS FULL TABLE PRDABPPCDB.Z_MID_R3_BOM_ORG1 Cost: 2,493  Bytes: 107,280  Cardinality: 1,788  
                    2 TABLE ACCESS FULL TABLE PRDABPPCDB.MST_BOMCOMPONENTSALT Cost: 6,172  Bytes: 52,636,539  Cardinality: 1,032,089  
                4 TABLE ACCESS FULL TABLE PRDABPPCDB.RPT_FP_SHORTAGE_ORDER Cost: 72  Bytes: 4,389  Cardinality: 133  

    2、拆分SQL,分段执行观察整个SQL语句的block,有针对性优化

    此处的优化是在表z_dim_product (数据量20万左右)上建立函数索引,lpad(product,18,'0') 

    简写SQL:

    SELECT MAX (hier11_code)
    FROM z_dim_product
    WHERE substr(product,length(product)-9,10) =  b.ITEM  (b 表是另一个关联表)

    修改后的SQL: 

    SELECT MAX (hier11_code)
    FROM z_dim_product
    WHERE lpad(product,18,'0') =  lpad(b.ITEM,18,'0') 

    3、大表优化充分利用分区和分区的索引

    4、从业务角度调整逻辑,改写SQL,这种方法往往是所有优化里效果最明显的。

    ..........

    后面34 的方法没有再上传SQL,有时间会继续记录个人的优化总结

       

  • 相关阅读:
    java类型转换
    JVM内存各个区域分工简单介绍
    用数组实现栈
    一些关于Spring的随笔
    设计模式学习笔记(三)之静(动)态代理模式、适配器模式
    浅谈经典排序算法
    PetStore项目总结
    设计模式学习笔记(二)之观察者模式、装饰者模式
    Spring的校验(Validator)
    设计模式学习笔记(一)之工厂模式、单例模式
  • 原文地址:https://www.cnblogs.com/flyingsanddream/p/5019982.html
Copyright © 2020-2023  润新知