explain plan VS execution plan
explain plan VS execution plan
explain plan 翻譯成中文應該稱作解釋計劃比較恰當。是oracle
對指定的SQL語句給出的理論上的或者稱作預期的執行計劃。
execution plan 翻譯成中文應該稱作執行計劃比較恰當。是oracle
對指定的SQL語句採取的實際的執行計劃。很多時候我們並不做這種區分,統一把兩者稱作執行計劃,並且把兩者當成是相同的東西,在多數情況下可以認為explain plan 等於 execution plan。
oracle 資料庫也是一個“言行不一的人”。那就是理論的執行計劃不總是和實際的執行計劃相同。下面建立一個測試表,並往其中填充測試資料。
SQL> edit
Wrote file afiedt.buf
1 create table test_plan
2 ( id varchar2(10) primary key,
3* object_name varchar2(40))
SQL> /
Table created.
SQL> insert into test_plan
2 select object_id,object_name
3 from dba_objects;
65558 rows created.
建立一個host variable ,供後續使用。為了後續的演示,這一步不可以省略。
SQL> variable obj_id number
SQL> exec :obj_id := 100;
PL/SQL procedure successfully completed.
SQL> print :obj_id
OBJ_ID
----------
100
收集物件的統計資訊,以便CBO可以有足夠的資訊來給出“正確”的執行計劃。
SQL> exec dbms_stats.gather_table_stats(user,'test_plan',cascade=>true);
PL/SQL procedure successfully completed.
使用autotrace 家族的命令來得到執行計劃(實際上是解釋計劃,理論上的執行計劃。)可以使用的是索引掃描,似乎合情合理。oracle是否真的這麼做那就說不準了。後面的幾個例子都是透過使用autotrace 家族的命令來的到的解釋計劃,解釋計劃的統計資訊等,根據使用的autotrace 命令的不同,輸出的結果也不同,但是無一例外這些都是解釋計劃相關的資訊。
SQL> set autotrace on explain
SQL> select *
2 from test_plan
3 where id = :obj_id;
ID OBJECT_NAME
-------------------- ----------------------------------------------------------------------
100 ORA$BASE
Execution Plan
----------------------------------------------------------
Plan hash value: 3457654460
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 31 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_PLAN | 1 | 31 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | SYS_C007392 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=:OBJ_ID)
SQL> set autotrace traceonly
SQL> /
Execution Plan
----------------------------------------------------------
Plan hash value: 3457654460
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Ti
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 31 | 2 (0)| 00
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_PLAN | 1 | 31 | 2 (0)| 00
|* 2 | INDEX UNIQUE SCAN | SYS_C007392 | 1 | | 1 (0)| 00
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=:OBJ_ID)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
330 consistent gets
0 physical reads
0 redo size
499 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> set autotrace on statistics
SQL> /
ID OBJECT_NAME
-------------------- --------------------------------------
100 ORA$BASE
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
330 consistent gets
0 physical reads
0 redo size
499 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> set autotrace on
SQL> /
ID OBJECT_NAME
-------------------- ----------------------------------------------------------------------
100 ORA$BASE
Execution Plan
----------------------------------------------------------
Plan hash value: 3457654460
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 31 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_PLAN | 1 | 31 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | SYS_C007392 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=:OBJ_ID)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
330 consistent gets
0 physical reads
0 redo size
499 bytes sent via SQL*Net to client
419 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
使用explain plan 命令得到了也是解釋計劃。
SQL> explain plan for
2 select *
3 from test_plan
4 where id = :obj_id;
Explained.
SQL> select * from table(dbms_xplan.display)
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------
Plan hash value: 3457654460
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 31 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_PLAN | 1 | 31 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | SYS_C007392 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------
2 - access("ID"=:OBJ_ID)
到這邊,我們可以知道autotrace 的一系列命令和explain plan 是做“高仿”的給出的並不是實際的執行計劃。那實際的執行計劃可以透過 dbms_xplan.display_cursor 來獲得。
14 rows selected.SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------
SQL_ID 3qyycjg6g8058, child number 0
-------------------------------------
select /*+ gather_plan_statistics*/ * from test_plan where id =:obj_id
Plan hash value: 289916773
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 330 |
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------
|* 1 | TABLE ACCESS FULL| TEST_PLAN | 1 | 1 | 1 |00:00:00.01 | 330 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("ID")=:OBJ_ID)
從輸出的對比我們可以知道實際上SQL語句:
select * from test_plan where id =:obj_id;
在執行的時候,並不會使用索引訪問,而是使用全表掃描。產生這個explain plan 和 execution plan不同的原因本質上是他們是在不同的環境下產生的,解釋計劃不會考慮繫結變數的資料型別和值,所以的繫結變數都當在varchar2,所以就有了我們上面在解釋計劃中看到的:
2 - access("ID"=:OBJ_ID)
而實際上在執行計劃中是:
filter(TO_NUMBER("ID")=:OBJ_ID)
oracle在執行該SQL語句的時候會把id 列轉換為 number 型別來和繫結變數的值相比較。
小結:明白explain plan (解釋計劃)和execution plan (執行計劃)的區別的意義是正確標識出SQL語句執行問題的前提。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26110315/viewspace-723569/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Explain for the Statistics of Execution PlanAI
- Explain PlanAI
- oracle execution planOracle
- USE EXPLAIN PLANAI
- Oracle EXPLAIN PLAN用法OracleAI
- explain plan 的用法AI
- Understanding Parallel Execution PlanParallel
- oracle explain plan for的用法OracleAI
- Error: cannot fetch last explain plan from PLAN_TABLEErrorASTAI
- ORACLE EXPLAIN PLAN的總結OracleAI
- Use the statspack to generate the accurate explain planAI
- explain plan 學習記錄AI
- 【Explain Plan】10g中的PLAN_TABLE$臨時表AI
- Using Statspack to Record Explain Plan DetailsAI
- 用EXPLAIN PLAN 分析SQL語句AISQL
- SAP ABAP SQL的execution plan和cacheSQL
- oracle 9i啟用Execution PlanOracle
- Retrieve SQL and Execution Plan from AWR SnapshotsSQL
- Oracle執行計劃Explain Plan 如何使用OracleAI
- oracle 使用explain plan分析查詢語句OracleAI
- EXPLAIN PLAN and SQL*PLUS AUTOTRACE may not generate actual plansAISQL
- toad顯示explain plan的問題AI
- Oracle 執行計劃(Explain Plan) 說明OracleAI
- autotrace explain plan 相關引數解釋AI
- Oracle 執行計劃(Explain Plan) 說明OracleAI
- EXPLAIN PLAN FOR 和 SET AUTOTRACE之間的差別AI
- 使用EXPLAIN PLAN來檢視執行計劃AI
- TOAD中檢視執行計劃(Explain Plan)AI
- (轉)oracle效能工具包Explain plan、Autotrace、TkprofOracleAI
- 配置oracle 解釋執行計劃--explain planOracleAI
- 【Explain Plan】檢視SQL的執行計劃AISQL
- 【最佳化】explain plan for 方式存取執行計劃AI
- [20171201]關於explain plan.txtAI
- set autot traceonly與explain plan for的一點小區別AI
- 適當採用Histogram 讓Oracle達成最優Execution PlanHistogramOracle
- 11G新特性,explain plan 可以評估出索引大小AI索引
- Script: Script to Simplify the Use of Explain Plan (Doc ID 1019631.6)AI
- autotrace 和explain plan for可能導致執行計劃錯誤AI