• PLSQL查询执行计划


    转:

    PLSQL查询执行计划 01(转)

    一般优化途径:
    如果能通过修改语句优化,比如查询条件或执行顺序,sql改不了,可以通过增加索引来解决,增加索引还不行,那就要考虑实现方式是否有问题了
    一段SQL代码写好以后,可以通过查看SQL的执行计划,初步预测该SQL在运行时的性能好坏,尤其是在发现某个SQL语句的效率较差时,我们可以通过查看执行计划,分析出该SQL代码的问题所在。  

    1、 打开熟悉的查看工具:PL/SQL Developer

    在PL/SQL Developer中写好一段SQL代码后,按F5,PL/SQL Developer会自动打开执行计划窗口,显示该SQL的执行计划。

    1.1.  PLSQL参数解释

           ID: 一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。

           Operation: 当前操作的内容。

           Rows: 当前操作的Cardinality,Oracle估计当前操作的返回结果集。

           Cost(CPU):Oracle 计算出来的一个数值(代价),用于说明SQL执行的代价。

           Time:Oracle 估计当前操作的时间。

    Oracle的优化器有两种:

    • RBO(Rule-Based Optimization) 基于规则的优化器
    • CBO(Cost-Based Optimization) 基于代价的优化器(Oracle 9I完全替代RBO)
    • |——CBO通过计算各种可能的执行计划的“代价”,即COST,从中选用COST最低的执行方案作为实际运行方案;

      依赖数据库对象的统计信息,统计信息的准确与否会影响CBO做出最优的选择,也就是对数据“敏感”。

    1.2   谓词说明

    CBO通过计算各种可能的执行计划的“代价”,即COST,从中选用COST最低的执行方案作为实际运行方案;

    它依赖数据库对象的统计信息,统计信息的准确与否会影响CBO做出最优的选择,也就是对数据“敏感”。

       access("A"."EMPNO"="B"."MGR")

           filter("A"."EMPNO"="B"."MGR")

       filter("B"."MGR" IS NOT NULL)

           Access: 表示这个谓词条件的值将会影响数据的访问路劲(表还是索引)。

           Filter:表示谓词条件的值不会影响数据的访问路劲,只起过滤的作用。

    1.3  统计信息说明

    db block gets : 从buffer cache中读取的block的数量    

    consistent gets: 从buffer cache中读取的undo数据的block的数量    

    physical reads: 从磁盘读取的block的数量    

    redo size: DML生成的redo的大小    

    sorts (memory) :在内存执行的排序量    

    sorts (disk) :在磁盘上执行的排序量    

     在看执行计划的时候,除了看执行计划本身,还需要看谓词和提示信息。 通过整体信息来判断SQL 效率。

    2、 执行顺序一般是:从右至左,从下至上
           看懂执行计划

    技巧总结:1.  同一级若没有子ID就最先执行

                      2.  同一级执行遵循最上最后先执行的原则

    INDEX RANGE SCAN  —>  TABLE ACCESS BY GLOBAL INDEX ROWID  —>  INDEX UNIQUE SCAN  —>  TABLE ACCESS BY INDEX ROWID  —>  NESTED LOOPS OUTER  —>  SORT GROUP BY  —>  SELECT STATEMENT, GOAL = ALL_ROWS

    3、 分析表的访问方式 

    • TABLE ACCESS FULL(全表扫描)
    • TABLE ACCESS BY ROWID(通过ROWID的表存取)
    • TABLE ACCESS BY INDEX SCAN(索引扫描)

    4.1 TABLE ACCESS FULL

    Oracle会读取表中所有的行,并检查每一行是否满足SQL语句中的 Where 限制条件;

    全表扫描时可以使用多块读(即一次I/O读取多块数据块)操作,提升吞吐量;

    使用建议:数据量太大的表不建议使用全表扫描,除非本身需要取出的数据较多,占到表数据总量的 5% ~ 10% 或以上

    4.2  TABLE ACCESS BY ROWID

    ROWID是由Oracle自动加在表中每行最后的一列伪列,既然是伪列,就说明表中并不会物理存储ROWID的值;

    你可以像使用其它列一样使用它,只是不能对该列的值进行增、删、改操作;

    一旦一行数据插入后,则其对应的ROWID在该行的生命周期内是唯一的,即使发生行迁移,该行的ROWID值也不变。

    让我们再回到 TABLE ACCESS BY ROWID 来:

    行的ROWID指出了该行所在的数据文件、数据块以及行在该块中的位置,所以通过ROWID可以快速定位到目标数据上,这也是Oracle中存取单行数据最快的方法

    4.3  TABLE ACCESS BY INDEX SCAN

    既存储每个索引的键值,也存储具有该键值的行的ROWID

    索引扫描步骤:

    Ⅰ:扫描索引得到对应的ROWID

    Ⅱ:通过ROWID定位到具体的行读取数据

    4、  索引扫描方式

    5.1  Index Unique Scan(唯一扫描)

    每次 只返回一条记录

    情景:unique primary key

    5.2  Index Range Scan(索引范围扫描)

    情景:索引列使用 范围操作符 > <

               组合索引,查询部分

               非唯一索引列 任何查询

    5.3  Index Full Scan(索引全扫描)——查询数据必须从索引列 全部直接得到

    5.4  Index Fast Full Scan(索引快速扫描)——类似Index Full Scan,但是它查询的数据 不进行排序

    5.5  Index Skip Scan(索引跳跃扫描)

    情景:复合索引的前导列(索引中第一列) 没有在查询语句中出现

    当Oracle发现前导列的唯一值个数很少时,会将每个唯一值都作为常规扫描的入口,在此基础上做一次查找,最后合并这些查询;

    假设表emp有ename(雇员名称)、job(职位名)、sex(性别)三个字段,并且建立了如 create index idx_emp on emp (sex, ename, job) 的复合索引;

    因为性别只有 '男' 和 '女' 两个值,所以为了提高索引的利用率,Oracle可将这个复合索引拆成 ('男', ename, job),('女', ename, job) 这两个复合索引;

    当查询 select * from emp where job = 'Programmer' 时,该查询发出后:

    Oracle先进入sex为'男'的入口,这时候使用到了 ('男', ename, job) 这条复合索引,查找 job = 'Programmer' 的条目;

    再进入sex为'女'的入口,这时候使用到了 ('女', ename, job) 这条复合索引,查找 job = 'Programmer' 的条目;

    最后合并查询到的来自两个入口的结果集。

  • 相关阅读:
    配置gem5-gpu模拟环境
    如何避免并发情况下的重复提交
    避免重复执行
    java线程池
    java动态代理
    Java 静态代理
    Java 静态代理和动态代理
    Spring的事务传播性
    mybatis配置(Configuration.xml)详解
    mybati之parameterType传递多个参数
  • 原文地址:https://www.cnblogs.com/libin6505/p/11906003.html
Copyright © 2020-2023  润新知