代码改变世界

案例:使用dbms_xplan.display_cursor无法获取执行计划

2019-12-10 16:57  AlfredZhao  阅读(447)  评论(0编辑  收藏

案例:使用dbms_xplan.display_cursor无法获取执行计划
环境:RHEL 6.5 + Oracle 11.2.0.4

在一次测试中发现使用dbms_xplan.display_cursor无法获取到刚刚执行成功的SQL执行计划,现象如下:

test@DEMO> select count(*) from t;

  COUNT(*)
----------
     86391

test@DEMO> @x

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID  9babjv8yq8ru3, child number 1

BEGIN DBMS_OUTPUT.GET_LINES(:LINES, :NUMLINES); END;

NOTE: cannot fetch plan for SQL_ID: 9babjv8yq8ru3, CHILD_NUMBER: 1
      Please verify value of SQL_ID and CHILD_NUMBER;
      It could also be that the plan is no longer in cursor cache (check v$sql_plan)


8 rows selected.

test@DEMO> get x 
  1* select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

正常应该显示我刚执行的SQL执行计划,可结果却没有,且显然这个sql_id为9babjv8yq8ru3的语句不是我刚执行的,看到对应SQL文本中有DBMS_OUTPUT关键字,进而想到去看下serveroutput的设置,是不是有影响:

test@DEMO> show serveroutput
serveroutput ON SIZE 1000000 FORMAT WORD_WRAPPED
test@DEMO> set serveroutput off
test@DEMO> show serveroutput
serveroutput OFF

可以看到serveroutput是开启的,正常默认情况应该是关闭,这里就先将其关闭后再试:

test@DEMO> select count(*) from t;

  COUNT(*)
----------
     86391

test@DEMO> @x

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID  cyzznbykb509s, child number 1
-------------------------------------
select count(*) from t

Plan hash value: 2966233522

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |      1 |00:00:00.05 |    1239 |
|   1 |  SORT AGGREGATE    |      |      1 |      1 |      1 |00:00:00.05 |    1239 |
|   2 |   TABLE ACCESS FULL| T    |      1 |  73056 |  86391 |00:00:00.03 |    1239 |
-------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=2)


18 rows selected.

可以正常显示执行计划了,看来的确是serveroutput开启影响到我这样看执行计划了。
那么我操作过程中并没有开启serveroutput,而默认就应该是off的。这时候想到是不是sqlplus预定义的glogin.sql文件中有对应的设置?去查看发现果然如此,具体如下:

cd $ORACLE_HOME/sqlplus/admin
vi glogin.sql 
...省略无关内容...
set serveroutput on size 1000000
...省略无关内容...

如果近期工作经常需要这样查看执行计划,就把set serveroutput这一行配置注释或者删除即可。