1. 程式人生 > >oracle sql的執行計劃如何檢視

oracle sql的執行計劃如何檢視

一、通過PL/SQL Dev工具
    1、直接File->New->Explain Plan Window,在視窗中執行sql可以檢視計劃結果。其中,Cost表示cpu的消耗,單位為n%,Cardinality表示執行的行數,等價Rows。
    2、先執行 EXPLAIN PLAN FOR   select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的執行計劃了,看到的結果和1中的一樣,所以使用工具的時候推薦使用1方法。
注意:PL/SQL Dev工具的Command window中不支援set autotrance on的命令。還有使用工具方法檢視計劃看到的資訊不全,有些時候我們需要sqlplus的支援。
 
二、通過sqlplus
1.最簡單的辦法
Sql> set autotrace on
Sql> select * from dual;
  執行完語句後,會顯示explain plan 與 統計資訊。
  這個語句的優點就是它的缺點,這樣在用該方法檢視執行時間較長的sql語句時,需要等待該語句執行成功後,才返回執行計劃,使優化的週期大大增長。如果不想執行語句而只是想得到執行計劃可以採用:
Sql> set autotrace traceonly
這樣,就只會列出執行計劃,而不會真正的執行語句,大大減少了優化時間。雖然也列出了統計資訊,但是因為沒有執行語句,所以該統計資訊沒有用處,如果執行該語句時遇到錯誤,解決方法為:
(1)在要分析的使用者下:
Sqlplus > @ ?
dbmsadminutlxplan.sql
(2) 用sys使用者登陸
Sqlplus > @ ?sqlplusadminplustrce.sql
Sqlplus > grant plustrace to user_name;
- - user_name是上面所說的分析使用者
 
 2.用explain plan命令
(1) sqlplus > explain plan for select * from testdb.myuser
(2) sqlplus > select * from table(dbms_xplan.display);
  上面這2種方法只能為在本會話中正在執行的語句產生執行計劃,即我們需要已經知道了哪條語句執行的效率很差,我們是有目的只對這條SQL語句去優化。其實,在很多情況下,我們只會聽一個客戶抱怨說現在系統執行很慢,而我們不知道是哪個SQL引起的。此時有許多現成的語句可以找出耗費資源比較多的語句,如:
SELECT ADDRESS, substr(SQL_TEXT,1,20) Text, buffer_gets, executions,
buffer_gets/executions AVG  FROM  v$sqlarea
WHERE executions>0 AND buffer_gets > 100000   ORDER BY 5;
ADDRESS      TEXT                     BUFFER_GETS    EXECUTIONS        AVG
-------- ---------------------------------------- ----------- ---------- ------------------------------------------------------------
66D83D64   select t.name,  (sel               421531        60104             7.01336017
66D9E8AC   select t.schema, t.n               1141739        2732             417.913250
66B82BCC   select s.synonym_nam             441261        6                73543.5
  從而對找出的語句進行進一步優化。當然我們還可以為一個正在執行的會話中執行的所有SQL語句生成執行計劃,這需要對該會話進行跟蹤,產生trace檔案,然後對該檔案用tkprof程式格式化一下,這種得到執行計劃的方式很有用,因為它包含其它額外資訊,如SQL語句執行的每個階段(如Parse、Execute、Fetch)分別耗費的各個資源情況(如CPU、DISK、elapsed等)。
 
3、啟用SQL_TRACE跟蹤所有後臺程序活動:
全域性引數設定: .OracleHome/admin/SID/pfile中指定: SQL_TRACE = true (10g)
    當前session中設定:
    SQL> alter session set SQL_TRACE=true;
    SQL> select * from dual;
    SQL> alter session set SQL_TRACE=false;
    對其他使用者進行跟蹤設定:
    SQL> select sid,serial#,username from v$session where username='XXX';
       SID    SERIAL# USERNAME
    ------ ---------- ------------------
       127      31923 A
       128      54521 B
    開啟跟蹤:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,true);
    關閉跟蹤:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,false);
    然後使用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
    全域性設定:
    OracleHome/admin/SID/pfile中指定: EVENT="10046 trace name context forever,level 12"
    當前session設定:
    開啟:SQL> alter session set events '10046 trace name context forever, level 8';
    關閉:SQL> alter session set events '10046 trace name context off';
    對其他使用者進行設定:
    SQL> select sid,serial#,username from v$session where username='XXX';
       SID    SERIAL# USERNAME
    ------ ---------- ------------------
       127      31923 A

    SQL> exec dbms_system.set_ev(127,31923,10046,8,'A');

5、使用tkprof格式化跟蹤檔案: (根據下面SQL語句得到的檔案都不存在該目錄下,鬱悶啊,懵懂啊...)

一般,一次跟蹤可以分為以下幾步:
1、界定需要跟蹤的目標範圍,並使用適當的命令啟用所需跟蹤。
2、經過一段時間後,停止跟蹤。此時應該產生了一個跟蹤結果檔案。
3、找到跟蹤檔案,並對其進行格式化,然後閱讀或分析。
--使用一下SQL找到當前session的跟蹤檔案:
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc' trace_file_namefrom( select p.spid from v$mystat m,v$session s, v$process pwhere m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr) p,( select t.instance from v$thread t,v$parameter vwhere 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    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= '27' and s. SERIAL#= '30' 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;
 
--查詢後使用tkprof命令,將TRACE檔案格式為到D盤的explain_format.txt檔案中
SQL> $tkprof d:/oracle/admin/FZLGFM/udump/fzlgfm_ora_3468.trc  d:/explain_format.txt

檔案內容大致如下(看不太懂....懵懂啊.....天啊....神啊.....過幾時就懂了/////////////)
TKPROF: Release 9.2.0.1.0 - Production on 星期二 4月 20 13:59:20 2010
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Trace file: d:/oracle/admin/FZLGFM/udump/fzlgfm_ora_3468.trc
Sort options: default
********************************************************************************
count    = number of times OCI procedure was executed
cpu      = cpu time in seconds executing
elapsed  = elapsed time in seconds executing
disk     = number of physical reads of buffers from disk
query    = number of buffers gotten for consistent read
current  = number of buffers gotten in current mode (usually for update)
rows     = number of rows processed by the fetch or execute call********************************************************************************
alter session set events '10046 trace name context forever, level 8'
 
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        1      0.00       0.00          0          0          0           0
 
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer goal: CHOOSE
Parsing user id: SYS