1. 程式人生 > >查看執行計劃

查看執行計劃

red tip 支持 輸出 數據訪問 根據 介紹 system one

1.工具介紹 總結:單純估算用autotrace,真實調優用DBMS_XPLAN帶參數 1、explain 因為綁定變量的原因,這個只能是估算 explain plan for select 3+5 from dual; select * from table(dbms_xplan.display()); select * from table(dbms_xplan.display(table_name=>‘PLAN_TABLE‘,statement_id=>null,format=>‘ALL‘)); 用explain plan解釋一個SQL,相關信息會默認被放到一個一個叫PLAN_TABLE的全局臨時表中。可以用這個來查看。 參數: table_name,默認‘PLAN_TABLE‘,如果別的一個表跟PLAN_TABLE有一樣的表結構,也可以讀取裏面的信息。 statement_id 默認null,即查該session最後的一條explain plan解釋的語句。 format 默認‘TYPICAL‘,全部是‘BASIC‘,‘TYPICAL‘,‘ALL‘,ALL的時候會顯示PROJECTION, ALIAS and information about REMOTE SQL if the operation is distributed。其實除了指定這3個級別外,顯示什麽信息也可以再通過後面的備註(減號代表去除相關信息) ‘ALL -PROJECTION -NOTE‘ #ALL級別,但不要投射與NOTE信息 ‘BASIC ROWS‘ --BASE下本來沒有ROWS信息,我們也可以給它加上。 還有其他選項,如:outline 每個連上來的用戶都可以使用plan_table,不用特別的權限,也不用讀取諸如v$plan這樣的視圖。 不會實際執行SQL,也不會在shared pool上生成該SQL的cursor,是生成了一個cursor不過是帶上explain plan for字眼的,而沒有獨立的該sql的cursor產生。 2、autotrace 真實/估算,忽略綁定變量,非執行. 可以看邏輯讀等數量 SET AUTOTRACE ON EXPLAIN 只顯示執行計劃 估算,因為沒執行 ON STATISTICS 只顯示執行的統計信息 AUTOTRACE ON 包含2,3兩項內容 真實,因為執行過 AUTOTRACE TRACEONLY 與ON相似,但不顯示語句的執行結果 真實,因為執行過 3.SQL_TRACE 在12c中文檔中提示:不再支持SQL_TRACE參數; 真實計劃,需要用TKPROF工具解析,可以獲得綁定變量值. alter session set sql_trace=true; alter session set sql_trace=false; exec dbms_system.set_sql_trace_in_session(9,437,true) exec dbms_system.set_sql_trace_in_session(9,437,false) 4.EVENT 10053 10046 真實計劃,研究執行計劃產生的原因 10046為增強版sql_trace 參考《10046事件》 參考《10046&10053的區別》 10053是檢查優化器行為的,實在搞不懂為什麽走那個計劃可以看看,用得較少。 10046可以檢查一些等待事件的內容,也可以獲取綁定變量,一般用得也比較少。 4.DBMS_XPLAN 真實計劃 4.1 dbms_xplan.display_cursor
  1. DBMS_XPLAN.DISPLAY_CURSOR(
  2. sql_id IN VARCHAR2 DEFAULT NULL,
  3. child_number IN NUMBER DEFAULT NULL,
  4. format IN VARCHAR2 DEFAULT ‘TYPICAL‘);
IOSTATS:會展示該SQL的累計IO統計信息,加了last就顯示最後一個。 MEMSTATS:只有開啟了PGA自動內存管理,即pga_aggregate_target不是0,我們才能使用這項,會展示使用了多少memory,多少bytes被交換到磁盤,一般來說用了hash-join,sort,group by等比較需要內存的操作才會收集。 ALLSTATS:是‘IOSTATS MEMSTATS‘的同義詞。 IO+內存 LAST:默認地展示都是該遊標的累積統計信息,加了LAST才會顯示最後一個。 RUNSTATS_TOT --為了向後兼容,相當於IOSTATS RUNSTATS_LAST --為了向後兼容,相當於IOSTATS LAST 查看該遊標最後一次的實際統計信息執行計劃 select * from table(dbms_xplan.display_cursor(‘fb8szhn9h5r95‘,null,‘allstats last‘)); 會將該遊標的累積執行信息列出,例如遊標執行過兩次後,starts,A-Rows,buffers也是上面的兩倍 select * from table(dbms_xplan.display_cursor(‘fb8szhn9h5r95‘,null,‘allstats‘)); 最詳細,匯集了普通模式的all與詳細模式的allstats,而且將默認不顯示的outline信息也顯示出來。 select * from table(dbms_xplan.display_cursor(‘fb8szhn9h5r95‘,null,‘all allstats last outline‘)); ------------------------------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | ------------------------------------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | | 3 (100)| | 25 |00:00:00.01 | 3 | 2 | |* 1 | COUNT STOPKEY | | 1 | | | | | 25 |00:00:00.01 | 3 | 2 | | 2 | TABLE ACCESS FULL| T1 | 1 | 25 | 54400 | 3 (0)| 00:00:01 | 25 |00:00:00.01 | 3 | 2 | ------------------------------------------------------------------------------------------------------------------------------ gather_plan_statistics看更詳細的輸出--能達到10046的粒度了 alter session set statistics_level=all; select /*+ gather_plan_statistics */ from t1 where rownum<10; Starts為該sql執行的次數。 E-Rows為執行計劃預計的行數。 A-Rows為實際返回的行數。A-Rows跟E-Rows做比較,就可以確定哪一步執行計劃出了問題。 A-Time為每一步實際執行的時間(HH:MM:SS.FF),根據這一行可以知道該sql耗時在了哪個地方。 Buffers為每一步實際執行的邏輯讀或一致性讀。 Reads為物理讀。 OMem、1Mem為執行所需的內存評估值,0Mem為最優執行模式所需內存的評估值,1Mem為one-pass模式所需內存的評估值。 0/1/M 為最優/one-pass/multipass執行的次數。 select t.* from v$sql s,table(dbms_xplan.display_cursor(s.sql_id,s.child_number,‘ADVANCED ALLSTATS LAST‘)) t where s.sql_id = ‘&SQL_ID‘ ; ----------------------------------------------------------------------------------------------------------- 4.2 dbms_xplan.display_awr. 展示awr信息庫(因為shared pool中age out)中的執行計劃--但是沒有謂詞條件 SELECT * FROM table(DBMS_XPLAN.DISPLAY_AWR(‘3hxb21q9h4t40‘,1367077082,null,‘all‘)); select * from table(dbms_xplan.display_awr(‘&sqlid‘,null,null,‘ADVANCED +PEEKED_BINDS‘)); 參考《xplan.display_awr.sql》 sql_id --輸入存儲在AWR中的sql_id,你可以先查dba_hist_sql_plan,dba_hist_sqltext,看看某個語句屬於什麽sql_id。 plan_hash_value --如果是null的話該sql_id所有的執行計劃會輸出。默認null db_id --如果忽略,默認就是當前的database format --參考display(),還是‘basic‘,‘typical‘,‘all‘這樣,默認typical 權限:用戶需要select on DBA_HIST_SQL_PLAN,DBA_HIST_SQLTEXT,V$DATABASE的權限。 查sql_id,根據sql文本查出sql_id ,可以從dba_hist_sqltext查。 來源:展示的執行計劃的信息,來源於dba_hist_sql_plan。 詳細:是否可以用allstats這樣查看更詳細的執行計劃,這可能得取決於你當時的sql有沒開啟手機詳細運行時統計信息。 ----------------------------------------------------------------------------------------------------------- 4.3 display_sql_plan_baseline 展示存儲在SPM中的SQL執行計劃 查看SPM中baseline的執行計劃:DBMS_XPLAN.DISPLAY_sql_plan_baseline SELECT * FROM table(DBMS_XPLAN.DISPLAY_sql_plan_baseline(‘SQL_a074c4f7bacd50da‘,‘SQL_PLAN_a0x64yyxcun6u06957ae0‘,‘ALL‘)); SELECT * FROM table(DBMS_XPLAN.DISPLAY_sql_plan_baseline(sql_handle => ‘SQL_351fadd1a0ec16be‘ )); SELECT * FROM table(DBMS_XPLAN.DISPLAY_sql_plan_baseline(plan_name => ‘SQL_PLAN_a0x64yyxcun6u06957ae0‘,‘ALL‘)); 格式: sql_handle SPM中的sql_handle相當於v$sql中的sql_id,默認Null plan_name SPM中唯一標識一個執行計劃,就像v$sql中的plan_hash_value。默認null。如果是null,那麽上面的sql_handle就必須指定。 format:參考display(),默認typical。 執行計劃來源於:DBA_SQL_PLAN_BASELINES 5.各種現成腳本是利器 display_cursor_9i.sql. —因為9i沒有display_cursor方法 printsql
2.執行計劃閱讀順序: 由上至下:在執行計劃中一般含有多個節點,相同級別(或並列)的節點,靠上的優先執行,靠下的後執行 從右向左:在某個節點下還存在多個子節點,先從最靠右的子節點開始執行。 靠光標大法即可,或者有些腳本裏面帶了執行的步驟 標量子查詢 可能違反最右最上原則,參考《Oracle SQL優化分析步驟》 執行計劃如果顯示是access,就表示這個謂詞條件的值將會影響數據的訪問路徑(表還是索引),而filter表示謂詞條件的值並不會影響數據訪問路徑,只起到過濾的作用 帶*號的是filter過濾 或 驅動access 動態采樣 如果在執行計劃中有如下提示: -dynamic sampling used for the statement 這提示用戶CBO當前使用的技術,需要用戶在分析計劃時考慮到這些因素。 當出現這個提示,說明當前表使用了動態采樣。 我們從而推斷這個表可能沒有做過分析 這裏會出現兩種情況: (1) 如果表沒有做過分析,那麽CBO可以通過動態采樣的方式來獲取分析數據,也可以或者正確的執行計劃。 (2) 如果表分析過,但是分析信息過舊,這時CBO就不會在使用動態采樣,而是使用這些舊的分析數據,從而可能導致錯誤的執行計劃。 在看執行計劃的時候,除了看執行計劃本身,還需要看謂詞和提示信息。 通過整體信息來判斷SQL 效率。 動態采樣適用範圍: 1.沒有統計信息,比如生成的中間臨時表 2.多列產生關聯,比如人為指定(11g還引入多列統計信息,但是是生成了一個列,代價大)

查看執行計劃