Oracle 檢視SQL的執行計劃

hexiaomail發表於2010-11-04
 Oracle 檢視SQL的執行計劃

1、直接產生執行計劃
SQL> set autotrace on explain
SQL> select * from dual;

D
-
X

Execution Plan
----------------------------------------------------------
Plan hash value: 272002086

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     2 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

SQL> set autotrace off

這樣執行方便,但是當遇到執行時間長的SQL就變得不太現實,它是先產生結果再生成執行計劃的。

關於Autotrace幾個常用選項的說明:

SET AUTOTRACE OFF ---------------- 不生成AUTOTRACE 報告,這是預設模式
SET AUTOTRACE ON EXPLAIN --------- AUTOTRACE只顯示優化器執行路徑報告
SET AUTOTRACE ON STATISTICS ------ 只顯示執行統計資訊
SET AUTOTRACE ON ----------------- 包含執行計劃和統計資訊
SET AUTOTRACE TRACEONLY -----------同set autotrace on,但是不顯示查詢輸出

在10G之前的版本中,需要單獨建立PLAN_TABLE並授予許可權,10g中自動建立PLAN_TABLE$不再需要這一步驟。
10g之前初始化PLAN_TABLE需要建立的步驟:
SQL> @?/rdbms/admin/utlxplan.sql
SQL> create public synonym plan_table for plan_table;
SQL> grant all on plan_table to public;

在10G中,用到的是資料字典PLAN_TABLE$而不是PLAN_TABLE表,
SQL> SET AUTOTRACE TRACEONLY;
SQL> select * from plan_table;


Execution Plan
----------------------------------------------------------
Plan hash value: 103984305

---------------------------------------------------------------------------------
| Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |             |     5 | 55405 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| PLAN_TABLE$ |     5 | 55405 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------

Note
-----
  - dynamic sampling used for this statement 


2、利用explain plan for語句產生執行計劃
SQL> explain plan for select * from dual;

Explained.

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

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------

Plan hash value: 272002086

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     2 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

8 rows selected.

SQL>
這樣可以直接產生執行計劃,沒有產生SQL結果,應該相當於SQL SERVER中的預執行計劃。 

另一種方式就是利用$ORACLE_HOME/rdbms/admin目錄下的utlxplp.sql檢視執行計劃;
其實utlxplp.sql檔案中就存在一個語句:select * from table(dbms_xplan.display);
例如:
SQL> explain plan for select count(*) from dual;

Explained.

SQL> @?/rdbms/admin/utlxplp.sql

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------

Plan hash value: 3910148636

-----------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------
|   0 | SELECT STATEMENT |      |     1 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE  |      |     1 |            |          |
|   2 |   FAST DUAL      |      |     1 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------

9 rows selected.

SQL>

3、啟用sql_trace跟蹤所有後臺程式活動
檢視全域性SQL_TRACE引數:
SQL> show parameter sql_trace;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sql_trace                            boolean     FALSE

全域性引數要求在引數檔案中設定資料庫重啟生效或通過alter system命令設定:
SQL> alter system set sql_trace=true scope=both;

System altered.

SQL> show parameter sql_trace;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sql_trace                            boolean     TRUE
SQL>

啟用會話級的SQL_TRACE跟蹤
SQL> alter session set sql_trace=true;

Session altered.

SQL> select count(*) from dual;

 COUNT(*)
----------
        1

SQL> alter session set sql_trace=false;

Session altered. 

對其他使用者進行跟蹤
SQL> select sid,serial#,username from v$session where username='MYUSER';

      SID    SERIAL# USERNAME
---------- ---------- ------------------------------
      143          5 MYUSER

SQL> exec dbms_system.set_SQL_TRACE_in_session(143,5,true);

PL/SQL procedure successfully completed.

SQL> exec dbms_system.set_SQL_TRACE_in_session(143,5,false);

PL/SQL procedure successfully completed. 

最後可以得用ORACLE工具tkprof格式化跟蹤檔案即可。

4、使用10046事業進行查詢
10046事件級別:    
Lv1 - 啟用標準的SQL_TRACE功能,等價於SQL_TRACE    
Lv4 - Level 1 + 繫結值(bind values)    
Lv8 - Level 1 + 等待事件跟蹤    
Lv12 - Level 1 + Level 4 + Level 8 

全域性設定格式,在引數檔案加入:
EVENT='10046 trace name context forever,level 12';

當前session的設定:
SQL> alter session set events '10046 trace name context forever, level 8';

Session altered.

SQL> select * from dual;

D
-
X

SQL> alter session set events '10046 trace name context off';

Session altered. 

跟蹤其他使用者:
SQL> select sid,serial#,username from v$session where username='MYUSER';

      SID    SERIAL# USERNAME
---------- ---------- ------------------------------
      142         71 MYUSER
      143          5 MYUSER

SQL> exec dbms_system.set_ev(143,5,10046,8,'A');

PL/SQL procedure successfully completed.

SQL> select * from dual;

D
-
X

SQL> exec dbms_system.set_ev(143,5,10046,0,'A');

PL/SQL procedure successfully completed. 

5、使用tkprof格式化跟蹤檔案
檢視當前session的跟蹤檔案:
SELECT    d .VALUE
      || '\'
      || LOWER (RTRIM ( i .INSTANCE, CHR ( 0 )))
      || '_ora_'
      || p . spid
      || '.trc' trace_file_name
  FROM (SELECT p . spid
          FROM v$mystat m, v$session s , v$process p
         WHERE m. statistic# = 1 AND s .SID = m.SID AND p . addr = s . paddr ) p ,
       (SELECT t .INSTANCE
          FROM v$thread t , v$parameter v
         WHERE v .NAME = 'thread'
           AND ( v .VALUE = 0 OR t . thread# = TO_NUMBER ( v .VALUE))) i ,
       (SELECT VALUE
          FROM v$parameter
         WHERE NAME = 'user_dump_dest' ) d ;

--當前會話
SQL> SELECT    d.VALUE
 2        || '\'
 3        || LOWER (RTRIM (i.INSTANCE, CHR (0)))
 4        || '_ora_'
 5        || p.spid
 6        || '.trc' trace_file_name
 7   FROM (SELECT p.spid
 8           FROM v$mystat m, v$session s, v$process p
 9          WHERE m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,
10        (SELECT t.INSTANCE
11           FROM v$thread t, v$parameter v
12          WHERE v.NAME = 'thread'
13            AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,
14        (SELECT VALUE
15           FROM v$parameter
16          WHERE NAME = 'user_dump_dest') d;

TRACE_FILE_NAME
------------------------------------------------------------------------------------

C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_3868.trc 

檢視其他session的跟蹤檔案
SELECT    d .VALUE
      || '\'
      || LOWER (RTRIM ( i .INSTANCE, CHR ( 0 )))
      || '_ora_'
      || p . spid
      || '.trc' trace_file_name
  FROM (SELECT p . spid
          FROM v$session s , v$process p
         WHERE s .SID = '143' AND s . serial# = '5' AND p . addr = s . paddr ) p ,
       (SELECT t .INSTANCE
          FROM v$thread t , v$parameter v
         WHERE v .NAME = 'thread'
           AND ( v .VALUE = 0 OR t . thread# = TO_NUMBER ( v .VALUE))) i ,
       (SELECT VALUE
          FROM v$parameter
         WHERE NAME = 'user_dump_dest' ) d ;

--其他session
SQL> SELECT    d .VALUE
 2        || '\'
 3        || LOWER (RTRIM ( i .INSTANCE, CHR ( 0 )))
 4        || '_ora_'
 5        || p . spid
 6        || '.trc' trace_file_name
 7    FROM (SELECT p . spid
 8            FROM v$session s , v$process p
 9           WHERE s .SID = '143' AND s . serial# = '5' AND p . addr = s . paddr ) p ,
10         (SELECT t .INSTANCE
11            FROM v$thread t , v$parameter v
12           WHERE v .NAME = 'thread'
13             AND ( v .VALUE = 0 OR t . thread# = TO_NUMBER ( v .VALUE))) i ,
14         (SELECT VALUE
15            FROM v$parameter
16           WHERE NAME = 'user_dump_dest' ) d ;

TRACE_FILE_NAME
---------------------------------------------------------------------------------------------

C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_3812.trc 


5、利用tkprof工具格式化跟蹤檔案
SQL> host tkprof C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_3868.trc F:\test\3868.txt

TKPROF: Release 10.2.0.4.0 - Production on Fri Sep 10 11:18:10 2010

Copyright (c) 1982, 2007, Oracle.  All rights reserved.



SQL> host tkprof C:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_3812.trc F:\test\3812.txt

TKPROF: Release 10.2.0.4.0 - Production on Fri Sep 10 11:18:37 2010

Copyright (c) 1982, 2007, Oracle.  All rights reserved.



--The End---

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9932141/viewspace-677386/,如需轉載,請註明出處,否則將追究法律責任。

相關文章