SQL效能的度量 - 透過explain和dbms_xplan包分析執行計劃
該工具需要訪問一張特殊的表plan_table,該表用於儲存執行計劃,在Oracle 10g之前需要用指令碼utlxplan.sql建立:
建表:
@?\rdbms\admin\utlxplan.sql
建同義詞:
create public synonym plan_table for plan_table;
授權:
grant all on plan_table to public;
Oracle 10g之後不再需要建立表plan_table,而是增加了資料字典表plan_table$,然後基於plan_table$建立了公共同義詞供使用者使用。
explain基本語法:
explain plan [set statement_id = 'stmt_id'] for sql_statement;
explain指令的執行結果儲存於表plan_table中,有幾種方法獲取執行計劃的詳細資訊:
1、直接查詢plan_table表
解釋計劃
explain plan for select count(*) from scott.emp;
查詢結果
col id for 999
col operation for a50
col options for a20
col object_name for a20
select id,
lpad(' ', 2 * depth) || operation || ' ' || options ||
decode(id, 0, substr(optimizer, 1, 6) || ' Cost = ' || to_char(cost)) operation,
options,
object_name,
position
from plan_table
where plan_id = (select max(plan_id) from plan_table)
order by id;
ID OPERATION OPTIONS OBJECT_NAME POSITION
---- -------------------------------------------------- -------------------- -------------------- ----------
0 SELECT STATEMENT ALL_RO Cost = 1 1
1 SORT AGGREGATE AGGREGATE 1
2 INDEX FULL SCAN FULL SCAN PK_EMP 1
或者用以下查詢,包含了執行計劃樹的level層次關係
col "Execute Plan" for a100
select id || ' ' || parent_id || ' ' || lpad(' ', 2 * level - 1) ||
operation || ' ' || options || ' ' || object_name || ' (Cost=' || cost || ')' as "Execute Plan"
from plan_table
start with id = 0
connect by prior id = parent_id;
Execute Plan
----------------------------------------------------------------------------------------------------
0 SELECT STATEMENT (Cost=1)
1 0 SORT AGGREGATE (Cost=)
2 1 INDEX FULL SCAN PK_EMP (Cost=1)
2、透過程式包dbms_xplan獲得執行計劃
1)獲得最近一次explain的執行計劃
col "PLAN_TABLE_OUTPUT" for a100
select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 2937609675
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FULL SCAN| PK_EMP | 14 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------
2)透過指定的語句ID來查詢
select * from table(dbms_xplan.display('plan_table', 'stmt_id'));
3)透過SQL_ID和子游標來查詢,該函式並不要求先做explain,顯示的資訊也較詳細,另外還有一個format引數可以做更詳細的定製。
select * from table(dbms_xplan.display_cursor('sql_id', 'child_number', 'format'));
sql_id為null時顯示最近一次執行的SQL的執行計劃,但注意要保持set serveroutput off,否則最後一句SQL將不是你執行的SQL,child number為null,則返回所有子游標的執行計劃。
可以透過在SQL語句中加入註釋,方便的獲取SQL_ID和CHILD_NUMBER資訊,如以下SQL,先執行一次
select /*12345*/ m.material_id, m.material_no, m.part_no, m.material_name, m.validaterule, m.validaterule2
from cmes.c_material_t m
where (regexp_like('641234HNGA080001A', m.validaterule, 'c') or
regexp_like('641234HNGA080001A', m.validaterule2, 'c'))
and m.deleted_flag = '0'
and rownum = 1;
查出它的ID:
select sql_id, child_number from v$sql where sql_text like '%12345%';
SQL_ID CHILD_NUMBER
------------- ------------
9jk2r7a64s470 0
cc274s1r7ab6w 0
因為以上包含"12345"註釋的語句被執行了兩條,所以因取先執行的第一條為實際的ID。
檢視執行計劃:
col PLAN_TABLE_OUTPUT for a100;
select * from table(dbms_xplan.display_cursor('9jk2r7a64s470', 0));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID 9jk2r7a64s470, child number 0
-------------------------------------
select /*12345*/ m.material_id, m.material_no, m.part_no, m.material_name, m.validaterule, m.validaterule2
from cmes.c_material_t m
where (regexp_like('641234HNGA080001A', m.validaterule, 'c') or
regexp_like('641234HNGA080001A', m.validaterule2, 'c'))
and m.deleted_flag = '0'
and rownum = 1;
Plan hash value: 1524529232
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
|* 1 | COUNT STOPKEY | | | | | |
|* 2 | TABLE ACCESS FULL| C_MATERIAL_T | 2 | 116 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM=1)
2 - filter(("M"."DELETED_FLAG"='0' AND ( REGEXP_LIKE
('641234HNGA080001A',"M"."VALIDATERULE",'c',<not feasible>)
檢視更詳細的執行計劃資訊,需要先設定統計級別為ALL,否則沒有A-ROWS等資訊
alter session set statistics_level = all;
或者在語句級別使用HINT
select /*+gather_plan_statistics*/
select m.material_id, m.material_no, m.part_no, m.material_name, m.validaterule, m.validaterule2
from cmes.c_material_t m
where (regexp_like('641234HNGA080001A', m.validaterule, 'c') or
regexp_like('641234HNGA080001A', m.validaterule2, 'c'))
and m.deleted_flag = '0'
and rownum = 1;
select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS'));
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------
SQL_ID fmu73t3umxm1r, child number 0
-------------------------------------
select m.material_id, m.material_no, m.part_no, m.material_name, m.validaterule,
m.validaterule2 from cmes.c_material_t m where (regexp_like('641234HNGA080001A',
m.validaterule, 'c') or regexp_like('641234HNGA080001A', m.validaterule2,
'c')) and m.deleted_flag = '0' and rownum = 1
Plan hash value: 1524529232
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------------
|* 1 | COUNT STOPKEY | | 1 | | 0 |00:00:00.01 | 16 |
|* 2 | TABLE ACCESS FULL| C_MATERIAL_T | 1 | 2 | 0 |00:00:00.01 | 16 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM=1)
2 - filter((( REGEXP_LIKE ('641234HNGA080001A',"M"."VALIDATERULE",'c',???)
這裡E-Rows是預估的返回行數,A-Rows是實際的返回行數。
format的高階應用可以顯示更多的資訊,特別是可以顯示繫結變數的具體值,這個非常有用。以下是推薦的使用格式
select * from table(dbms_xplan.display_cursor(null,null,'ADVANCED ALLSTATS LAST PEEKED_BINDS'));
allstats:iostats + memstats,iostats顯示該遊標累計執行的io統計資訊(buffers, reads),memstats顯示累計執行的pga使用資訊(omem 1mem used-mem)
last:僅顯示最後一次執行的統計資訊
advanced:顯示outline、query block name、column projection等資訊
peeked_binds:列印解析時使用的繫結變數
如以下操作可以顯示非常詳細的執行計劃和繫結變數等資訊
alter session set statistics_level = all;
var a varchar2(20);
exec :a := 'EMP';
select object_id from dba_objects where object_name = :a;
select * from table(dbms_xplan.display_cursor(null,null,'ADVANCED ALLSTATS LAST PEEKED_BINDS'));
dbms_xplan程式包還有一個函式display_awr可以獲取AWR報告中指定SQL_ID的執行計劃
col PLAN_TABLE_OUTPUT for a100;
select * from table(dbms_xplan.display_awr('9jk2r7a64s470'));
該函式獲取的執行計劃來自dba_hist_sql_plan檢視,透過歷史資料記錄,甚至一些被老化的SQL執行計劃仍然可以被查詢到。
3、透過指令碼utlxpls.sql或utlxplp.sql獲得執行計劃
@?\rdbms\admin\utlxpls.sql
或
@?\rdbms\admin\utlxplp.sql
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 2937609675
-------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FULL SCAN| PK_EMP | 14 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------
看一下這兩個指令碼的內容,該方法實際是呼叫了方法2中的程式包
get ?\rdbms\admin\utlxpls.sql
......
41* select plan_table_output from table(dbms_xplan.display('plan_table',null,'serial'));
42
get ?\rdbms\admin\utlxplp.sql
......
40* select * from table(dbms_xplan.display());
41
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28974745/viewspace-2150271/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL效能的度量 - 透過v$sql_plan查詢執行計劃SQL
- MySQL——通過EXPLAIN分析SQL的執行計劃MySqlAI
- explain執行計劃分析AI
- 使用dbms_xplan包來獲得sql語句的執行計劃SQL
- 【Explain Plan】檢視SQL的執行計劃AISQL
- 透過執行計劃中的CONCATENATION分析sql問題SQL
- 透過分析SQL語句的執行計劃最佳化SQL(總結)SQL
- 透過10053事件分析一個SQL執行計劃事件SQL
- (4) MySQL中EXPLAIN執行計劃分析MySqlAI
- [轉]透過分析SQL語句的執行計劃最佳化SQL(總結)SQL
- 透過查詢檢視sql執行計劃SQL
- mysql執行計劃explainMySqlAI
- mysql explain 執行計劃MySqlAI
- DBMS_XPLAN檢視執行計劃
- SQL執行計劃分析SQL
- oracle執行計劃的使用(EXPLAIN)OracleAI
- 在MySQL中使用explain查詢SQL的執行計劃MySqlAI
- Explain執行計劃詳解AI
- explain 查詢執行計劃AI
- oracle dbms_xplan獲取執行計劃Oracle
- 用DBMS_XPLAN來展示執行計劃
- 用 Explain 命令分析 MySQL 的 SQL 執行AIMySql
- 透過空間佔用和執行計劃瞭解SQL Server的行儲存索引SQLServer索引
- 通過分析SQL語句的執行計劃優化SQL 二SQL優化
- MySQL Explain執行計劃 - 詳解MySqlAI
- 十六、Mysql之Explain執行計劃MySqlAI
- mysql explain 執行計劃詳解MySqlAI
- MySQL執行計劃EXPLAIN詳解MySqlAI
- ORACLE執行計劃 explain說明OracleAI
- 通過分析SQL語句的執行計劃優化SQL(總結)SQL優化
- 通過分析SQL語句的執行計劃優化SQL語句SQL優化
- 檢視一個正在執行的sql的執行計劃(explain for connection processlist_id)SQLAI
- mysql調優之——執行計劃explainMySqlAI
- Oracle執行計劃Explain Plan 如何使用OracleAI
- MongoDb學習之Explain執行計劃MongoDBAI
- Explain For理論執行計劃相關AI
- Oracle 執行計劃(Explain Plan) 說明OracleAI
- Oracle 執行計劃(Explain Plan) 說明OracleAI