zoukankan      html  css  js  c++  java
  • Oracle 执行计划说明

      生成SQL的执行计划是Oracle在对SQL做硬解析时的一个非常重要的步骤,它制定出一个方案告诉Oracle在执行这条SQL时以什么样的方式访问数据:索引还是全表扫描,是Hash Join还是Nested loops Join等。先看一个例子:

    -bash-3.00$ sqlplus hr/hr123  #以hr用户登录数据库
    
    SQL> set autotrace traceonly;  --开启autotrace功能
    SQL> select
      2     t1.first_name,last_name
      3  from  employees t1, jobs t2
      4  where t1.job_id=t2.job_id;
    
    107 rows selected.
    
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1445457117
    
    -------------------------------------------------------------------------------
    | Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |           |   107 |  2568 |     3   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS FULL| EMPLOYEES |   107 |  2568 |     3   (0)| 00:00:01 |
    -------------------------------------------------------------------------------
    
    
    Statistics
    ----------------------------------------------------------
              8  recursive calls
              0  db block gets
             17  consistent gets
              0  physical reads
              0  redo size
           3058  bytes sent via SQL*Net to client
            462  bytes received via SQL*Net from client
              9  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
            107  rows processed
    
    SQL> 

    执行计划中字段解释:

    1 ID: 一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。
    2 Operation: 当前操作的内容。
    3 Rows: 当前操作的Cardinality,Oracle估计当前操作的返回结果集。
    4 Cost(CPU):Oracle 计算出来的一个数值(代价),用于说明SQL执行的代价。
    5 Time:Oracle 估计当前操作的时间。

      Cardinality值表示CBO预期从一个行源(row source)返回的记录数,这个行源可能是一个表,一个索引,也可能是一个子查询。   在Oracle 9i中的执行计划中,Cardinality缩写成Card。 在10g中,Card值被rows替换。

      Cardinality的值对于CBO做出正确的执行计划来说至关重要。 如果CBO获得的Cardinality值不够准确(通常是没有做分析或者分析数据过旧造成),在执行计划成本计算上就会出现偏差,从而导致CBO错误的制定出执行计划。

      在多表关联查询或者SQL中有子查询时,每个关联表或子查询的Cardinality的值对主查询的影响都非常大,甚至可以说,CBO就是依赖于各个关联表或者子查询Cardinality值计算出最后的执行计划。

    统计信息说明:

    1 db block gets : 从buffer cache中读取的block的数量    
    2 consistent gets: 从buffer cache中读取的undo数据的block的数量    
    3 physical reads: 从磁盘读取的block的数量    
    4 redo size: DML生成的redo的大小    
    5 sorts (memory) :在内存执行的排序量    
    6 sorts (disk) :在磁盘上执行的排序量 

      Physical Reads通常是我们最关心的,如果这个值很高,说明要从磁盘请求大量的数据到Buffer Cache里,通常意味着系统里存在大量全表扫描的SQL语句,这会影响到数据库的性能,因此尽量避免语句做全表扫描,对于全表扫描的SQL语句,建议增 加相关的索引,优化SQL语句来解决。

    用以下语句可以查看数据缓冲区的命中率:

     1 SQL> SELECT name, value FROM v$sysstat WHERE name IN ('db block gets', 'consistent gets','physical reads');
     2 
     3 NAME                                                                  VALUE
     4 ---------------------------------------------------------------- ----------
     5 db block gets                                                        439264
     6 consistent gets                                                      195214
     7 physical reads                                                        10667
     8 
     9 SQL> 
    10 
    11 --数据缓冲区的使用命中率=1 - ( physical reads / (db block gets + consistent gets) )。
    12 
    13 SQL> select 1-(10667/(439264+195214)) from dual;
    14 
    15 1-(10667/(439264+195214))
    16 -------------------------
    17                .983187754
    18 
    19 SQL> 

      查询出来的结果Buffer Cache的命中率应该在90%以上,否则需要增加数据缓冲区的大小。

    动态分析:

      如果在执行计划中有如下提示:

    Note
    ------------
       -dynamic sampling used for the statement

      这提示用户CBO当前使用的技术,需要用户在分析计划时考虑到这些因素。 当出现这个提示,说明当前表使用了动态采样。 我们从而推断这个表可能没有做过分析。

    这里会出现两种情况:

    1. 如果表没有做过分析,那么CBO可以通过动态采样的方式来获取分析数据,也可以或者正确的执行计划。
    2. 如果表分析过,但是分析信息过旧,这时CBO就不会在使用动态采样,而是使用这些旧的分析数据,从而可能导致错误的执行计划。
  • 相关阅读:
    一百二十三:CMS系统之登录功能
    一百二十二:CMS系统之页面抽离和登录页面
    一百二十一:CMS系统之注册后跳转到上一个页面
    一百二十:CMS系统之注册功能前后端逻辑
    Python基础语法习题二
    编程语言分类和Python解释器介绍
    VS Code设置中文和配置Python环境
    Windows10系统下安装python2和python3双版本
    Python下载与安装
    前端开发之jQuery位置属性和筛选方法
  • 原文地址:https://www.cnblogs.com/polestar/p/3153203.html
Copyright © 2011-2022 走看看