oracle 执行计划 随笔

  • 查看执行计划的两种常用方式:

1.explain 

SQL> explain plan for select * from emp;

SQL> select * from table(dbms_xplan.display);

2.autotrace

SQL> set autotrace on

SQL> select * from dept;

  • 执行计划的执行顺序:

缩进相同时,最上面的最先执行;

同一级如果某个动作没有子ID就最先执行;

同一级的动作执行时遵循最上最右先执行的原则;

  • 表访问的几种方式:

1.全表扫描(TABLE ACCESS FULL)

oracle读取表中所有的行,并检查每一行是否满足SQL语句中的 Where 限制条件;是以多块读的方式读取数据,每次i/o可以读取多个数据块,提高系统的吞吐量;在大表上不建议使用全表扫描,除非取出的数据表较多,超过5%-10%;使用并行查询时。

2.通过ROWID的值存取扫描(TABLE ACCESS BY ROWID)

rowid指出了该行的数据信息在该块中的位置,所以通过rowid存取数据可以快速定位,是oracle存取单行数据最快的方法;该方法不会用到多快读操作,每次i/o只能读取一个块。

3.索引扫描(INDEX SCAN)

①索引唯一扫描:通过唯一索引查找数据对应的rowid,然后通过rowid直接从表中获取数据;如果存在unique或primary约束,oracle经常实现唯一性索引。

②索引范围扫描:使用一个索引存取多行数据;在唯一索引列上使用范围操作符(如:>   <   <>   >=   <=   between);在组合索引上,只使用部分列进行查询(查询时必须包含前导列,否则会走全表扫描);对非唯一索引列上进行的任何查询。

③索引全扫描:进行全索引扫描时,查询出的数据都必须从索引中可以直接得到(注意全索引扫描只有在CBO模式下才有效);

④索引快速扫描:扫描索引中的所有的数据块,与 INDEX FULL SCAN 类似,但是一个显著的区别是它不对查询出的数据进行排序(即数据不是以排序顺序被返回)

⑤索引跳跃扫描:有时候复合索引的前导列(索引包含的第一列)没有在查询语句中出现,oralce也会使用该复合索引,这时候就使用的INDEX SKIP SCAN;前提条件:表有一个复合索引,且在查询时有除了前导列(索引中第一列)外的其他列作为条件,并且优化器模式为CBO时。

  • 表连接的几种方式:

1.SORT MERGE JOIN(排序-合并连接)

       JOIN 关键字用于将两张表作连接,一次只能连接两张表,JOIN 操作的各步骤一般是串行的(在读取做连接的两张表的数据时可以并行读取);表(row source)之间的连接顺序对于查询效率有很大的影响,对首先存取的表(驱动表)先应用某些限制条件(Where过滤条件)以得到一个较小的row source,可以使得连接效率提高。

       驱动表(Driving Table):

表连接时首先存取的表,又称外层表(Outer Table),这个概念用于 NESTED LOOPS(嵌套循环) 与 HASH JOIN(哈希连接)中;如果驱动表返回较多的行数据,则对所有的后续操作有负面影响,故一般选择小表(应用Where限制条件后返回较少行数的表)作为驱动表。

       匹配表(Probed Table):

又称为内层表(Inner Table),从驱动表获取一行具体数据后,会到该表中寻找符合连接条件的行。故该表一般为大表(应用Where限制条件后返回较多行数的表)。

2.NESTED LOOPS(嵌套循环)

        内部连接过程:

取出 row source 1 的 row 1(第一行数据),遍历 row source 2 的所有行并检查是否有匹配的,取出匹配的行放入结果集中

取出 row source 1 的 row 2(第二行数据),遍历 row source 2 的所有行并检查是否有匹配的,取出匹配的行放入结果集中

……

若 row source 1 (即驱动表)中返回了 N 行数据,则 row source 2 也相应的会被全表遍历 N 次。

因为 row source 1 的每一行都会去匹配 row source 2 的所有行,所以当 row source 1 返回的行数尽可能少并且能高效访问 row source 2(如建立适当的索引)时,效率较高。

         嵌套循环的表有驱动顺序,注意选择合适的驱动表。嵌套循环连接有一个其他连接方式没有的好处是:可以先返回已经连接的行,而不必等所有的连接操作处理完才返回数据,这样可以实现快速响应。

        应尽可能使用限制条件(Where过滤条件)使驱动表(row source 1)返回的行数尽可能少,同时在匹配表(row source 2)的连接操作关联列上建立唯一索引(UNIQUE INDEX)或是选择性较好的非唯一索引,此时嵌套循环连接的执行效率会变得很高。若驱动表返回的行数较多,即使匹配表连接操作关联列上存在索引,连接效率也不会很高。

3.HASH JOIN(哈希连接) :

哈希连接只适用于等值连接(即连接条件为  =  )

HASH JOIN对两个表做连接时并不一定是都进行全表扫描,其并不限制表访问方式;

内部连接过程简述:

取出 row source 1(驱动表,在HASH JOIN中又称为Build Table) 的数据集,然后将其构建成内存中的一个 Hash Table(Hash函数的Hash KEY就是连接操作关联列),创建Hash位图(bitmap)

取出 row source 2(匹配表)的数据集,对其中的每一条数据的连接操作关联列使用相同的Hash函数并找到对应的 a) 里的数据在 Hash Table 中的位置,在该位置上检查能否找到匹配的数据

HASH JOIN的三种模式:

1) OPTIMAL HASH JOIN:OPTIMAL 模式是从驱动表(也称Build Table)上获取的结果集比较小,可以把根据结果集构建的整个Hash Table都建立在用户可以使用的内存区域里。

2): ONEPASS HASH JOIN :从驱动表(也称Build Table)上获取的结果集较大,无法将根据结果集构建的Hash Table全部放入内存中时,会使用 ONEPASS 模式。

3): MULTIPASS HASH JOIN:当内存特别小或者相对而言Hash Table的数据特别大时,会使用 MULTIPASS 模式。MULTIPASS会多次读取磁盘数据,应尽量避免使用该模式。

  • 表连接的两种类型:

1.INNER JOIN(内连接):只返回两表中相匹配的记录

①等值连接(连接条件为  

②非等值连接(连接条件为 非 =  ,如  >  >=  <  <=  等)

2.OUTER JOIN(外连接)

①LEFT OUTER JOIN(可简写为 LEFT JOIN,左外连接):返回的结果不仅包含符合连接条件的记录,还包含左边表中的全部记录。(若返回的左表中某行记录在右表中没有匹配项,则右表中的返回列均为空值)

②RIGHT OUTER JOIN( RIGHT JOIN,右外连接):返回的结果不仅包含符合连接条件的记录,还包含右边表中的全部记录。(若返回的右表中某行记录在左表中没有匹配项,则左表中的返回列均为空值)

③FULL OUTER JOIN( FULL JOIN,全外连接):返回左右两表的全部记录。(左右两边不匹配的项都以空值代替)

(+) 操作符是Oracle特有的表示法,用来表示外连接(只能表示 左外、右外 连接),需要配合Where语句使用。

特别注意:(+) 操作符在左表的连接条件上表示右连接,在右表的连接条件上表示左连接

猜你喜欢

转载自blog.csdn.net/haojiubujian920416/article/details/82151240