1. 程式人生 > >Oracle 檢視執行計劃

Oracle 檢視執行計劃

-- Start

EXPLAIN PLAN

我們可以通過 EXPLAIN PLAN 語句生成執行計劃,該語句把執行計劃儲存到一個叫做 PLAN_TABLE 的表中,我們可以通過查詢這個表來檢視執行計劃。下面是一個簡單例子。

-- 生成執行計劃
EXPLAIN PLAN 
SET STATEMENT_ID = 'test'
FOR
select * from employees where employee_id < 10;

-- 由於 PLAN_TABLE 表非常複雜,Oracle 提供下面的方式察看執行計劃
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE', 'test', 'ALL'));

-- 如果你想察看更多細節,你也可以直接查詢表
select * from plan_table where statement_id = 'test'

autotrace

如果你使用的是 sqlplus 工具,你還可以通過它提供了 autotrace 功能來檢視執行計劃,你只需要下面的兩步,非常簡單,下面是一個簡單的例子。

-- 第一步: 開啟 autotrace
SQL> set autotrace on

-- 第二步: 執行 SQL 語句
SQL> select * from test;

V$SQL_PLAN

上面檢視執行計劃的方式有一個缺陷,它們必須由人觸發,隨著執行環境,時間,統計資訊等的不同,執行計劃有可能不同,有沒有辦法檢視已經執行過 SQL 的執行計劃呢?答案是肯定的,下面是一個簡單的例子。

-- 第一步: 通過下面的語句找到 SQL_ID 
select SQL_ID,SQL_TEXT from v$sql 
where sql_text like '%KAFKA_MSG_QUEUE%';

-- 第二步: 通過下面的方式檢視執行計劃
select * from V$SQL_PLAN where SQL_ID='g7b1uz8n2mdvf' 
order by CHILD_NUMBER, id;

-- 注意,上面的語句可以查詢出該語句多次的執行計劃,你可以加上時間來過濾
select * from V$SQL_PLAN where SQL_ID='g7b1uz8n2mdvf' 
and "TIMESTAMP"=TIMESTAMP '2015-08-20 19:38:06.000'
order by CHILD_NUMBER, id

-- 上面語句的結果可讀性差,試一試下面的語句吧
select '| Operation                         |Object Name                    |  Rows | Bytes|   Cost |'
	as "Explain Plan in library cache:" from dual
union all
select rpad('| '||substr(lpad(' ',1*(depth-1))||operation||
       decode(options, null,'',' '||options), 1, 35), 36, ' ')||'|'||
       rpad(decode(id, 0, '----------------------------',
       substr(decode(substr(object_name, 1, 7), 'SYS_LE_', null, object_name)
       ||' ',1, 30)), 31, ' ')||'|'|| lpad(decode(cardinality,null,'  ',
       decode(sign(cardinality-1000), -1, cardinality||' ',
       decode(sign(cardinality-1000000), -1, trunc(cardinality/1000)||'K',
       decode(sign(cardinality-1000000000), -1, trunc(cardinality/1000000)||'M',
       trunc(cardinality/1000000000)||'G')))), 7, ' ') || '|' ||
       lpad(decode(bytes,null,' ',
       decode(sign(bytes-1024), -1, bytes||' ',
       decode(sign(bytes-1048576), -1, trunc(bytes/1024)||'K',
       decode(sign(bytes-1073741824), -1, trunc(bytes/1048576)||'M',
       trunc(bytes/1073741824)||'G')))), 6, ' ') || '|' ||
       lpad(decode(cost,null,' ', decode(sign(cost-10000000), -1, cost||' ',
       decode(sign(cost-1000000000), -1, trunc(cost/1000000)||'M',
       trunc(cost/1000000000)||'G'))), 8, ' ') || '|' as "Explain plan"
from v$sql_plan sp
where sp.SQL_ID='g7b1uz8n2mdvf' 
and "TIMESTAMP"=TIMESTAMP '2015-08-20 19:38:06.000';

怎麼樣?看不懂執行計劃?看看下面的文章吧?

如果你覺得執行計劃有問題,那麼很有可能是因為表或索引的統計資訊沒有更新,不知道怎麼檢視統計資訊?看看 《》 吧

-- 

-- 宣告:轉載請註明出處

-- Last edited on 2015-08-28

-- Created by ShangBo on 2015-07-28

-- End