zoukankan      html  css  js  c++  java
  • [z]Oracle性能优化-读懂执行计划

    http://blog.csdn.net/lifetragedy/article/details/51320192

    Oracle的执行计划

     

    得到执行计划的方式

     
     
     

    Autotrace例子

     
     
     

    使用Explain

     
     
    [sql] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. explain plan set STATEMENT_ID='testplan'  
    2. for select * from dual;  


     
    [sql] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. select lpad(' ',5*(level-1))||operation operation, options,  
    2.        object_name, cost,position  
    3.   from plan_table  
    4.     start with id=0 and STATEMENT_ID='testplan'  
    5.     connect by prior id=parent_id ;  


    怎样看执行计划

     
     
     

    看懂执行计划前先需要了解的一些知识


    伪列-ROWID

     
    rowid是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的。对每个表都有一个rowid的伪列,但是表中并不物理存储ROWID列的值。不过你可以像使用其它列那样使用它,但是不能删除改列,也不能对该列的值进行修改、插入。一旦一行数据插入数据库,则rowid在该行的生命周期内是唯一的,即即使该行产生行迁移,行的rowid也不会改变。 
     

    Recursive SQL

     
    有时为了执行用户发出的一个sql语句,Oracle必须执行一些额外的语句,我们将这些额外的语句称之为‘recursive calls’或‘recursive SQL statements’。如当一个DDL语句发出后,ORACLE总是隐含的发出一些recursive SQL语句,来修改数据字典信息,以便用户可以成功的执行该DDL语句。当需要的数据字典信息没有在共享内存中时,经常会发生Recursive calls,这些Recursive calls会将数据字典信息从硬盘读入内存中。用户不比关心这些recursive SQL语句的执行情况,在需要的时候,ORACLE会自动的在内部执行这些语句。当然DML语句也都可能引起recursive SQL。简单的说,我们可以将触发器视为recursive SQL。 
     
     

    Row Source and Predicate

     
    • Row Source(行源):用在查询中,由上一操作返回的符合条件的行的集合,即可以是表的全部行数据的集合;也可以是表的部分行数据的集合;也可以为对上2个row source进行连接操作(如join连接)后得到的行数据集合。
    • Predicate(谓词):一个查询中的WHERE限制条件
     

    Driving Table

     
    Driving Table(驱动表):该表又称为外层表(OUTER TABLE)。这个概念用于嵌套与HASH连接中。如果该row source返回较多的行数据,则对所有的后续操作有负面影响。注意此处虽然翻译为驱动表,但实际上翻译为驱动行源(driving row source)更为确切。一般说来a,是应用查询的限制条件后,返回较少行源的表作为驱动表,所以如果一个大表在WHERE条件有有限制条件(如等值限制),则该大表作为驱动表也是合适的,所以并不是只有较小的表可以作为驱动表,正确说法应该为应用查询的限制条件后,返回较少行源的表作为驱动表。在执行计划中,应该为靠上的那个row source,后面会给出具体说明。
     
     

    Probed Table

     
    Probed Table(被探查表):该表又称为内层表(INNER TABLE)。在我们从驱动表中得到具体一行的数据后,在该表中寻找符合连接条件的行。所以该表应当为大表(实际上应该为返回较大row source的表)且相应的列上应该有索引。 
     
     

    组合索引(concatenated index) 

    由多个列构成的索引,如create index idx_emp on emp(col1, col2, col3, ……),则我们称idx_emp索引为组合索引。在组合索引中有一个重要的概念:引导列(leading column),在上面的例子中,col1列为引导列。当我们进行查询时可以使用”where col1 = ? ”,也可以使用”where col1 = ? and col2 = ?”,这样的限制条件都会使用索引,但是”where col2 = ? ”查询就不会使用该索引。所以限制条件中包含先导列时,该限制条件才会使用该组合索引。 
     

    可选择性(selectivity)

     
    比较一下列中唯一键的数量和表中的行数,就可以判断该列的可选择性。如果该列的”唯一键的数量/表中的行数”的比值越接近1,则该列的可选择性越高,该列就越适合创建索引,同样索引的可选择性也越高。在可选择性高的列上进行查询时,返回的数据就较少,比较适合使用索引查询。 
     

    oracle访问数据的存取方法(高实战) 


     

    索引扫描的细分(Index Scan)

     
     
     

    表连接(高实战1)

     
     
     

    表连接(高实战2)

     
     

    表连接(高实战3)

     
     
     

    表连接(高实战4)

     
     

    不同表连接的相对速度

     
     
     

    一个简单的执行计划(在PLSQL-DEVELOPER里按F5,不是F4哈)

     
     

    再来看2个执行计划(1)

     
     
     

    再来看2个执行计划(2)

     
     
     

    Oracle中的Hints(提示)

     
     
     

    优化器提示

     
     
     

    表连接提示

     
     
     

    索引提示

     
     
     

    并行提示

     
     
     

    表访问提示

     
     
     

    索引和SQL语句的正确使用

     
     

    使用ORACLE自带的SQLPLUS

     
     

    如何让SQLPLUS据有AUTOTRACE功能

    • 以sys用户连接;
    • 运行$ORACLE_HOME/sqlplus目录下的plustrace.sql脚本;
    • grant plustrace to public,对所有用户有效;
    • 在sql*plus 中运行set autot on命令,将自动跟踪sql的执行计划并提供sql统计资料;
     

    Consistent Gets

     
     
     
    第1个不加order by的SQL肯定比第2个SQL效率高是毋庸置疑的。


    但是为什么第2个SQL的consistent gets如此之少?


    原因有如下两点:


    1. 通常情况下,不在logical RAM buffer中的数据要通过physical reads来读取,而physical reads后通常会紧跟着一个consistent gets。因此一般情况下consistent gets是要比physical reads大的。但是有一个特例,如果physical reads得到的数据直接用于HASH或者SORT,则只记为physical reads不记为consistent gets。所以加上order by后有可能physical reads多但consistent gets少。不过这个原因不是我这里现象产生的原因,因为我这个实验里根本没有physical reads。
    2. arraysize的影响。arraysize是指读取数据时一次读取得到的行数。这个值默认为15,使用show arraysize命令可以查看。一个数据块例如有100条记录,那么并不是读取这个块一次就能取到所有数据,以arraysize=15为例,就要有100/15=7次consistent gets。把arraysize设置得大一点可以降低consistent gets,不过有时候可能会消耗更多的资源。如果我们做select count(0) from test;操作,那么Oracle会把arraysize暂时设为test的行数,因此consistent gets会很少。很少:
     
     
     

    AUTOTRACE的几个常用选项

     
    set autotrace off : 不生成autotrace 报告,这是缺省模式
    set autotrace on explain:  autotrace只显示优化器执行路径报告
    set autotrace on statistics: 只显示执行统计信息
    set autotrace on: 包含执行计划和统计信息
    set autotrace traceonly: 同set autotrace on,但是不显示查询输
     
     

    set autotrace on explain

     
     
     

    set autotrace on statistics

     
     
     

    set autotrace traceonly

     
     
     

    set autotrace traceonly explain

     
     
     

    另一种查看SQL计划的方式-Explain plan

     
     
    说明:用以查看SQL语句的执行计划


    准备:


    运行$ORACLE_HOME/rdbms/admin目录下的utlxplan.sql脚本
    建立plan_table表
    执行方案:explain plan for SQL
     

    Explain Plan-查看执行方案

     
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
  • 原文地址:https://www.cnblogs.com/jjj250/p/6068757.html
Copyright © 2011-2022 走看看