Oracle里另外一些典型的执行计划(4)

wKiom1izlLjSEuI7AAA1mFOFEOk454.png

最后执行如下SQL:

select t1.empno,t2.ename from scott.emp t1,emp_temp t2;

wKiom1izlXiyXZooAAA_mOQNiBc965.png

从上述显示内容可以看出,现在该SQL的执行计划走的是对表EMP_TEMP和表EMP上主键PK_EMP的笛卡儿连接,因为上述SQL中没有指定连接条件。此处执行计划的步骤是首先全表扫描表EMP_TEMP,扫描结果记为结果集1;接着对表EMP上的主键PK_EMP做索引快速全扫描,并将扫描结果load进PGA中,然后对结果集1和结果集2做笛卡儿连接,最后笛卡儿连接的结果就是上述SQL的最终执行结果。执行计划中关键字“BUFFER SORT”就是表示Oracle会借用PGA并把扫描结果load进去,这样做的好处是省掉了相应的缓存在SGA中所带来的种种额外开销(如持有、释放相关Latch等)。PGA常常用来做排序,这可能就是“BUFFER SORT”中关键字SORT的由来。

需要注意的是,BUFFER SORT不一定会排序,也可能会排序,也可能不会。

看一个SQL是否排序,最直观的方法就是查看其统计信息中"sorts(memory)"和"sorts(disk)"的值,如果这两个指标的值大于0,则说明该SQL在执行时经历过排序。但遗憾的是,这两个指标对BUFFER SORT而言是不准的,此时我们就需要借助目标SQL真实执行计划中"Column Projection Information"部分"keys"的值来判断到底所对应的BUFFER SORT有没有排序。"#keys"的值就表示该执行步骤实际排序列的数量,如果"#keys"值大于0时,则表示该执行步骤确实排过序了。

看如下SQL:

set autotrace traceonly

zx@MYDB>select t1.ename,t2.loc from scott.emp t1,scott.dept t2;

 

56 rows selected.

 

 

Execution Plan

----------------------------------------------------------

Plan hash value: 2034389985

 

-----------------------------------------------------------------------------

| Id  | Operation       | Name | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------

|   0 | SELECT STATEMENT     |      |   56 | 784 |   10   (0)| 00:00:01 |

|   1 |  MERGE JOIN CARTESIAN|      |   56 | 784 |   10   (0)| 00:00:01 |

|   2 |   TABLE ACCESS FULL  | DEPT |    4 |     32 |   3   (0)| 00:00:01 |

|   3 |   BUFFER SORT       |     |   14 |  84 |   7   (0)| 00:00:01 |

|   4 |    TABLE ACCESS FULL | EMP  |  14 |  84 |   2   (0)| 00:00:01 |

-----------------------------------------------------------------------------

 

 

Statistics

----------------------------------------------------------

    315  recursive calls

      0  db block gets

     70  consistent gets

     11  physical reads

      0  redo size

       1831  bytes sent via SQL*Net to client

    557  bytes received via SQL*Net from client

      5  SQL*Net roundtrips to/from client

      7  sorts (memory)

      0  sorts (disk)

     56  rows processed

注意到上述显示内容中“统计信息”部分的sorts(memory)的值为7,但由于该SQL中出现了ID=3的执行步骤“BUFFER SORT”,所以这并不一定能说明该SQL在执行时经历过排序。

我们来看一下执行坟墓中id=3的执行步骤“BUFFER SORT”所对应的“#keys”的值:

zx@MYDB>select sql_id,sql_text from v$sql where sql_text = 'select t1.ename,t2.loc from scott.emp t1,scott.dept t2';

 

SQL_ID           SQL_TEXT

-------------------- ----------------------------------------------------------------------------------------------------

3dmxcxk72fwr4       select t1.ename,t2.loc from scott.emp t1,scott.dept t2

 

zx@MYDB>select * from table(dbms_xplan.display_cursor('3dmxcxk72fwr4',0,'advanced'));

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d635c9385f10fe5e228849c179cafd9e.html