大家可能之前都了解过执行计划的查看方式,比如explain plan for,set autot ... 但是其实这些方式查看的执行计划并非真实执行计划,而是oracle根据统计信息等信息通过CBO计算出来的执行计划, 都来自于PLAN_TABLE,这是一个会话级的临时表,其储存的执行计划往往与真实执行计划相差甚远。 本文介绍如何查看执行SQL的真实执行计划。 方法一:使用statistics_level = all的方法查看 1、更改系统统计收集参数为all,session级别即可,
注意:all是一个全面收集,包括 OS以及sql执行路径方面的一些统计信息,相对来说比较耗费资源,因此千万不能设置全局为all,会话级别使用即可。
SQL> alter session set statistics_level = all; Session altered.
2、执行待查看执行计划的SQL语句
SQL> select a.email from hr.employees a where rownum<=5; EMAIL ------------------------- ABANDA ABULL ACABRIO AERRAZUR AFRIPP
3、执行如下命令查看真实执行计划
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ SQL_ID aw1d4an00b4za, child number 0 ------------------------------------- select a.email from hr.employees a where rownum<=5 Plan hash value: 2484301839 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 5 |00:00:00.01 | 2 | |* 1 | COUNT STOPKEY | | 1 | | 5 |00:00:00.01 | 2 | | 2 | INDEX FULL SCAN| EMP_EMAIL_UK | 1 | 5 | 5 |00:00:00.01 | 2 | ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(ROWNUM<=5) 19 rows selected.
方法二:添加hint提示符方式查看
1、在执行SQL中添加加/*+ gather_plan_statistics */ hint,例如:
SQL> select /*+ gather_plan_statistics */ a.email from hr.employees a where rownum<=5; EMAIL ------------------------- ABANDA ABULL ACABRIO AERRAZUR AFRIPP
2、使用如下命令查看SQL语句真实执行计划
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last')); PLAN_TABLE_OUTPUT ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ SQL_ID 6qu4asp22hx3p, child number 0 ------------------------------------- select /*+ gather_plan_statistics */ a.email from hr.employees a where rownum<=5 Plan hash value: 2484301839 ------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 5 |00:00:00.01 | 2 | |* 1 | COUNT STOPKEY | | 1 | | 5 |00:00:00.01 | 2 | | 2 | INDEX FULL SCAN| EMP_EMAIL_UK | 1 | 5 | 5 |00:00:00.01 | 2 | ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(ROWNUM<=5) 20 rows selected.
