oracle执行计划解释

时间:2021-06-24 07:39:28

本文转载于网络,方便自己查询使用。      

  .相关概念
    1·rowid
,伪列:就是系统自己给加上的,每个表都有一个伪列,不并不是物理存在。它不能修改,删除,和添加, rowid在该行的生命周期是唯一的,如果向数据库插入一列,只会引起行的变化,但是rowid并不会变。
    2·recursive sql
概念:当用户执行一些SQL语句时,会自动执行一些额外的语句,我们把这些额外的SQL语句称为 “recursive calls” 或者是“recursive sql statement”,当在执行一个DDL语句时,Oracle总会隐含的发出一些Recursiv sql语句,用于修改数据字典,如果数据字典没有在共享内存中,则就执行“resursive calls”,它会把数据字典从物理读取到共享内存。当然DMLselect语句都可能引起recursive SQL
    3·row source
行源:在查询中,由上一操作返回的符合条件的数据集,它可能是整个表,也可能是部分,当然也可以对2个表进行连接操作(join)最后得到的数据集
    4·predicate:
一个查询中的where限制条件
    5·driving table
驱动表:该表又成为外层表,这个感念用于内嵌和HASH连接中,如果返回数据较大,会有负面影响,
      
返回行数据较小的适合做驱动表
    6·probed table
被探查表:该表又称为内层表,我们在外层表中取得一条数据,在该表中寻找符合连接的条件的行。
    7·
组合索引(concatenated index)由多个列组成的索引,在组合索引中有一个重要的概念,就是引导索引,
            create index idx_tab on tab(col1,col2,col3),    
            indx_tab
则称为组合索引,
            col1
则称为引导列
     
在查询条件where后,必须使用引导索引,才会使用该组合索引
    8.
可选择性(selectivity)比较一下列中唯一键的数量和表中的行数,就可以判断该列的可选择性。 如果该列的
    
唯一键的数量/表中的行数的比值越接近1,则该列的可选择性越高,该列就越适合创建索引,同样索引的可选择性也越高。
    
在可选择性高的列上进 行查询时,返回的数据就较少,比较适合使用索引查询。
       
.Oracle访问数据的存取方法
    1.
全表扫描(Full tabel scans,FTS)
           
为了实现全表扫描,Oracle读取数据库中的每一行,并检查每一行是否满足语句的where限制条件一个多块读操作,
           
可以使io能读取多块数据块。减少了IO次数,提高了系统的吞吐量。在多块读的方法的使用下,可以高效的实现
           
数据库全表扫描,而且,中有在全表扫描的情况下,在可以使用多块读的方法。在这个种访问模式下,数据块只
           
读一次。
            
【注意】
           
使用FTS的前提是,在较大的表中,不建议使用FTS,除非取出的数据较多,超过总量的5%-10%,或者使用并行查询时
    2.
通过rowid的表存取
           
行的ROWID指向了该行的数据文件,数据块,以及在数据块中的位置,使用rowid能快速的定位到要取得数据的行上,
           
Oracle中,这是取得单行最快的方式。
           
【注意】
           
该存取方法,不会用到多块读操作,一次IO只能读取一个数据块。
    3.
索引扫描(index scan index lookup)
           
索引扫描时通过index查找到对应行的rowid,然后通过rowid从数据库中得到具体的数据。该方法分为两个步骤,
           
1)扫描索引得到得到rowid
       
说明:索引中不止储存着索引值,还存放的行的rowid
           
2)通过rowid得到表中的数据
           
【注意】
             1.
由于索引经常使用,因此绝大多数都Cache到内存当中,所以第一步通常是逻辑IO,即数据可以从内存中取得
            2.
但是对第二步来说,如果数据比较大,就不可能存放在内存,因此是个物理操作,是极其耗时间的,因此,从大表中
           
进行索引扫描,如果数量大于总数的5%-10%,则效力会下降很多
            3.
如果索引的数据都能在表中能找到,就可以避免第二步操作,避免了不必要的IO。效力会很高。
            4.
如果SQL语句会对索引排序,因为索引已经预先排好了戏,索引在执行计划中不需要在对索引排序。
   
根据索引的类型与where限制条件的不同,有4种数据类型的索引
            1.
唯一索引(index unique scan)
       
通过唯一索引查找一个数值,通常是rowid,如果表中存在unique,或者是primary key的话,Oracle通常实现
       
唯一索引
            2.
索引范围扫描(index range scan
       
如果要取得多行数据,通常在唯一索引上加上范围操作,例如(>,<
        *
使用index rang scan的三种情况
        (a)
在唯一索引上有where条件筛选
        (b)
在组合索引上,使用部分列进行查询,导致查询出多行
        (c)
对非唯一 索引列进行的任何查询
            3.
索引全扫描(index full scan)
       
与全表扫描想对应的就是全索引扫描,它必要保证要取得的数据都从索引中直接得到
       
例:
        Index BE_IX is a concatenated index on big_emp
empno ename
           SQL> explain plan for select empno
ename from big_emp order by empnoename
            4.
索引快速扫描(index fash full scan)
       
索引快速扫描和index full scan相似,不会对查询出的数据进行排序。        
       
.表之间的连接
    
根据row source连接的条件不同,可以分为等值连接(where a.col3=b.col4)非等值连接(where a.col3>b.col4)外连接
    (where a.col3=b.col4(+))
    1.
典型的连接类型
            (a)
排序--合并连接(sort merge join,SMJ
            (b)
嵌套循环(nested loops,NL)
            (c)
哈希连接(hash join,)
    A.
排序--合并连接
            1)
首先生成row source1需要的数据,让后对连接关联的列进行排序。
            2)
然后生成row source2需要的数据,然后对这些数据按照与row socurce1相对应的操作关联列进行排序。
            3)
将两边排好序的数据进行合并操作,将2row source按照连接条件连接起来。
            [
注意]
            ·.
如果row source已经在关联上列上被排序,那个连接操作就不会执行sort操作,将大大的提高效率,因为排序时极其
   
消耗资源的,预先被排序的row source包括索引,或者已经排好序的列。
            ·.
排序是非常耗时的操作,尤其是大表,基于这个原因,SMJ通常不是一个好的解决办法,如果排序的工作早已做好
   
那将极大的提高效率
  ·.
对于非等值连接,这种连接方式的效率是比较高的。
    B.
圈套循环。
           
在连接有驱动表的概念,实际上连接过程就是2层嵌套循环,所以外层表的值也少也好。
            [
执行原理]
       
从内部表来看,需要得到外层表的每一行,去匹配内部表的所有行,因此保持外部表竟可能小,和高效率访问内部表,是
       
连接性能的关键。
            [
优点]
        nested loops
可以返回已经连接的行,而不必等待所有的行连接完,因此能快速响应,特别适合用在
       
需要快速响应的语句中。
         C.hash join
           
较小的row source用来构建hash tablebitmap,而第二个用来被hansed,并与第一个生成的hash table进行匹配。 bitmap用来作为一种较快查询的方法,用来检查hash table是否有匹配的行,特别在表大的情况下,不能容纳在内存 中,这个连接方法非常有效。这个链接,也有驱动表的概念,有来构造hash table,bitmap的表叫驱动表,如果被
     
构建的hash table,bitmap都能容纳在内存中,这个效率非常高。
           
【注意】
           1)
要使哈希连接有效,需要设置HASH_JOIN_ENABLED=TRUE,缺省情况下该参数为TRUE,另外,不要忘了还要设置 hash_area_size参数,以使哈希连接高效运行,因为哈希连接会在该参数指定大小的内存中运行,过小的参数  会使哈希连接的性能比其他连接方式还 要低
   2)
只能用于等值连接。
   3)
2个较大的row source之间连接时会取得相对较好的效率,在一个row source较小时则能取得更好的效率。

        解释结果
    1.AND-EQUAL
该步骤具有两个或更多个子步骤,每一个子步骤返回一系列的ROWID.AND-EQUAL操作选择的是索引子操作返回的rowid        
    2.BITMAP
          conversoin to rowids --
将位图从位图索引转换成可以用于提取实际资料的一系列的ROWID
            conversoin from rowids --
将一系列的ROWID转换成位图表示
            conversoin count --
对位图的行数进行统计
            index single scan --
为单个索引提取位图
            index range scan --
返回的位图是一定范围的关键值
            index full scan --
扫描整个位图索引
            MERGE        --
合并连个位图,并作为一个位图返回结果
            Minus --
该操作是merge的相反操作,而且可以具有两个或3个字操作并返回位图
       
第一个子操作返回的位图用作起点,第一个位图减去第二个位图中提供的所有行。如果第二个位图为空,那么所有的
        null
列也将被减去。
        or  --
将两个位图作为输入
    3.connect by --
分层提取行,因为查询采用了CONNECT BY C从句
    4.concatenaction --
合并多个行集为一行。
    5.count --
计算从表中也选择的行数
            stopkey --
计算的行数被查询语句中的where 中的 rownum所限制
    6.filter --
将一系列的行数作为输入,并过滤到where从句查询而得到的结果
    7.firsh row --
提取查询结果集的第一行
    8.for udpate --
为提取的行加锁。
    9.hash join --
使用散列连接法连接两张表
    10.index 
            unique --
从索引中查找唯一值
            range scan --
从一定范围中查找,是按照升序的方式
            range scans desc --
扫描行在一定范围之内,但是是按照降序的方式
    11.inlist iterator --
in谓词中为一个值执行一次或者多次操作
    13 intersection --
将两个结果集合并成一个集,并返回在它们之间出现的共同的值
    14 merger join --
提供共同值,用来连续两个结果集的结果。是内连接
             output --

             anit --

             seml --

    15 nosted loops --
该操作涉及到2个子程序的操作,第一个返回一个行集,在用行集中的每一行,执行第二个子操作。
            output --
用于执行外部圈套循环
    16 partition [
分区] --执行一个或者多个分区操作,partition-start,partition-stop将提供分区的范围
        singnal  --
显示操作将在单个分区上执行
        iterator        --
在许多个分区中执行
        all  --
显示操作将在所有分区上执行 
        inlist --
显示操作在分区上执行,并用IN谓词驱动
    17 projection --
采用多个查询作为输入,并返回单个记录集。常和intersection,minus, unqie使用        
    18 sort 
            aggregate --
在行集上采用分组函数
            unique  --
对行集排序,去掉重复的行
            join  --
merger相同
            group up --
分组排序
            orday by --
按照orday by进行排序
    19 table access 
        full --
显示指定表中的所有行
        cluster --
与特定索引键进行匹配的所有行
        hash  --
散列
        by rowid --
显示oracle表将从rowid提取
    20 unqie
显示两个集,并去掉重复行
    21 view
产生视图,并返回结果行集。