要為一個語句生成執行計劃,可以有幾種方法
要為一個語句生成執行計劃,可以有3種方法: 1).最簡單的辦法 Sql> set autotrace on Sql> select * from dual;執行完語句后,會顯示explain plan 與統計信息。
這個語句的優點就是它的缺點,這樣在用該方法查看執行時間較長的sql語句時,需要等待該語句執行成功后,才返回執行計劃,使優化的周期大大增長。 如果不想執行語句而只是想得到執行計劃可以采用:Sql> set autotrace traceonly這樣,就只會列出執行計劃,而不會真正的執行語句,大大減少了優化時間。
雖然也列出了統計信息,但是因為沒有執行語句,所以該統計信息沒有用處,如果執行該語句時遇到錯誤,解決方法為: (1)在要分析的用戶下:Sqlplus > @ ?\rdbms\admin\* (2) 用sys用戶登陸Sqlplus > @ ?\sqlplus\admin\*plus > grant plustrace to user_name; - - user_name是上面所說的分析用戶 2).用explain plan命令 (1) sqlplus > @ ?\rdbms\admin\* (2) sqlplus > explain plan set statement_id ='???' for select ……………… 注意,用此方法時,并不執行sql語句,所以只會列出執行計劃,不會列出統計信息,并且執行計劃只存在plan_table中。所以該語句比起set autotrace traceonly可用性要差。
需要用下面的命令格式化輸出,所以這種方式我用的不多: set linesize 150 set pagesize 500 col PLANLINE for a120 SELECT EXECORD EXEC_ORDER, PLANLINE FROM (SELECT PLANLINE, ROWNUM EXECORD, ID, RID FROM (SELECT PLANLINE, ID, RID, LEV FROM (SELECT lpad(' ',2*(LEVEL),rpad(' ',80,' '))|| OPERATION||' '|| -- Operation DECODE(OPTIONS,NULL,'','('||OPTIONS || ') ')|| -- Options DECODE(OBJECT_OWNER,null,'','OF '''|| OBJECT_OWNER||'.')|| -- Owner DECODE(OBJECT_NAME,null,'',OBJECT_NAME|| ''' ')|| -- Object Name DECODE(OBJECT_TYPE,null,'','('||OBJECT_TYPE|| ') ')|| -- Object Type DECODE(ID,0,'OPT_MODE:')|| -- Optimizer DECODE(OPTIMIZER,null,'','ANALYZED','', OPTIMIZER)|| DECODE(NVL(COST,0)+NVL(CARDINALITY,0)+NVL(BYTES,0), 0,null,' (COST='||TO_CHAR(COST)||',CARD='|| TO_CHAR(CARDINALITY)||',BYTES='||TO_CHAR(BYTES)||')') PLANLINE, ID, LEVEL LEV, (SELECT MAX(ID) FROM PLAN_TABLE PL2 CONNECT BY PRIOR ID = PARENT_ID AND PRIOR STATEMENT_ID = STATEMENT_ID START WITH ID = * AND STATEMENT_ID = *ENT_ID) RID FROM PLAN_TABLE PL1 CONNECT BY PRIOR ID = PARENT_ID AND PRIOR STATEMENT_ID = STATEMENT_ID START WITH ID = 0 AND STATEMENT_ID = 'aaa') ORDER BY RID, -LEV)) ORDER BY ID; 上面這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; 從而對找出的語句進行進一步優化。當然我們還可以為一個正在運行的會話中運行的所有SQL語句生成執行計劃,這需要對該會話進行跟蹤,產生trace文件,然后對該文件用tkprof程序格式化一下,這種得到執行計劃的方式很有用,因為它包含其它額外信息,如SQL語句執行的每個階段(如Parse、Execute、Fetch)分別耗費的各個資源情況(如CPU、DISK、elapsed等)。
3).用dbms_system存儲過程生成執行計劃 因為使用dbms_system存儲過程可以跟蹤另一個會話發出的sql語句,并記錄所使用的執行計劃,而且還提供其它對性能調整有用的信息。因其使用方式與上面2種方式有些不太一樣,所以在附錄中單獨介紹。
這種方法是對SQL進行調整比較有用的方式之一,有些情況下非它不可。 以上是我對于這個問題的解答,希望能夠幫到大家。