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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SAP ABAP SQL的execution plan和cacheSQL
- Oracle執行計劃Explain Plan 如何使用OracleAI
- "The Alberta Plan for AI Research" - "Research Plan" from Richard SuttonAI
- Virtualbox host plan
- 4.2.1.1 Plan the PDBs
- MySQL 8.0 Reference Manual(讀書筆記58節--Understanding the Query Execution Plan(1))MySql筆記
- MySQL 8.0 Reference Manual(讀書筆記59節--Understanding the Query Execution Plan(2))MySql筆記
- sql_plan_baselineSQL
- 1030 Travel Plan (30分)
- 【Lintcode】1891. Travel Plan
- SQL PLAN Management的測試SQL
- PAT甲級1030 Travel Plan
- Study Plan For Algorithms - Part44Go
- Study Plan For Algorithms - Part45Go
- Study Plan For Algorithms - Part46Go
- Study Plan For Algorithms - Part38Go
- Study Plan For Algorithms - Part39Go
- Study Plan For Algorithms - Part40Go
- Study Plan For Algorithms - Part28Go
- Study Plan For Algorithms - Part19Go
- Study Plan For Algorithms - Part33Go
- Study Plan For Algorithms - Part37Go
- Study Plan For Algorithms - Part29Go
- Study Plan For Algorithms - Part12Go
- Study Plan For Algorithms - Part14Go
- Study Plan For Algorithms - Part11Go
- Study Plan For Algorithms - Part13Go
- Study Plan For Algorithms - Part15Go
- Study Plan For Algorithms - Part4Go
- Study Plan For Algorithms - Part1Go
- Study Plan For Algorithms - Part6Go
- Study Plan For Algorithms - Part16Go
- Study Plan For Algorithms - Part17Go
- Study Plan For Algorithms - Part7Go
- Study Plan For Algorithms - Part9Go
- Study Plan For Algorithms - Part3Go
- Study Plan For Algorithms - Part10Go
- Study Plan For Algorithms - Part27Go
- Study Plan For Algorithms - Part26Go