【SQL 調優】繫結變數窺測
繫結變數窺測:在物理最佳化階段,查詢最佳化器會窺測繫結變數的值,將它作為文字來使用。這種方法的問題是它生成的執行計劃會依賴第一次生成執行計劃時所提供的值。
--建立索引
SQL> create index i_obj_id on t_var_peek(object_id);
索引已建立。
已用時間: 00: 00: 00.25
---執行計劃選擇了 range scan
SQL> select count(object_id) from t_var_peek where object_id < 10;
已用時間: 00: 00: 00.01
執行計劃
----------------------------------------------------------
Plan hash value: 1952566611
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01|
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| I_OBJ_ID | 8 | 104 | 2 (0)| 00:00:01|
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"<10)
Note
- dynamic sampling used for this statement
----使用繫結變數
SQL> exec :x1 :=999;
PL/SQL 過程已成功完成。
已用時間: 00: 00: 00.01
SQL> select count(object_id) from t_var_peek where object_id < :x1;
已用時間: 00: 00: 00.00
執行計劃
----------------------------------------------------------
Plan hash value: 1952566611
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| I_OBJ_ID | 3439 | 44707 | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"
-----
- dynamic sampling used for this statement
----此時 返回的行數和cost 大小是和 :X1=999 的值是一樣的。說明第一次最佳化是使用值999來執行的。結果,查詢最佳化器就選擇了INDEX RANGE SCAN。由於遊標是共享的,因此是這個選擇影響了第二次使用9作為條件的查詢語句。
SQL> exec :x1 :=9;
PL/SQL 過程已成功完成。
已用時間: 00: 00: 00.01
SQL> select count(object_id) from t_var_peek where object_id < :x1;
已用時間: 00: 00: 00.00
執行計劃
----------------------------------------------------------
Plan hash value: 1952566611
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| I_OBJ_ID | 3439 | 44707 | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"
-----
- dynamic sampling used for this statement
---在使用 <9 時 請注意執行計劃的rows 和 bytes cost的值!
SQL> select count(object_id) from t_var_peek where object_id < 9;
已用時間: 00: 00: 00.01
執行計劃
----------------------------------------------------------
Plan hash value: 1952566611
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| I_OBJ_ID | 7 | 91 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"<9)
Note
-----
- dynamic sampling used for this statement
--此時:x1 的值還是 9 但是執行計劃的和前面 :X1 =999 和 :X1=999 的執行計劃是一樣的,明顯的發生了變數窺測!
SQL> select count(object_id) from t_var_peek where object_id < :x1;
已用時間: 00: 00: 00.00
執行計劃
----------------------------------------------------------
Plan hash value: 1952566611
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| I_OBJ_ID | 3439 | 44707 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"
-----
- dynamic sampling used for this statement
只要遊標還儲存在庫快取中並且可以被共享,就可以被重用。不管與它相關的執行計劃的效率如何,這種事情都會發生。
解決辦法:
為了解決這個問題,Oracle11g中引入了一個稱為擴充套件的遊標共享(extended cursor sharing,也稱為適應性遊標共享,adaptive cursor sharing)的新功能。它的目的是在重用一個已經存在的但是會導致執行效率低下的遊標時能夠自動進行識別。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21601207/viewspace-680717/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 繫結變數窺測變數
- 【sql調優】繫結變數與CBOSQL變數
- 【sql調優】使用繫結變數(二)SQL變數
- 【sql調優】使用繫結變數(一)SQL變數
- 繫結變數窺測的演變變數
- 繫結變數窺視測試案例變數
- Oracle 繫結變數窺探Oracle變數
- 繫結變數之繫結變數窺探(Bind Peeking)變數
- 繫結變數優缺點、使用、繫結變數窺探、 Oracle自適應共享遊標變數Oracle
- oracle繫結變數窺視(zt)Oracle變數
- Oracle 變數繫結與變數窺視合集Oracle變數
- 10g繫結變數窺探變數
- 【原創】Oracle 變數繫結與變數窺視合集Oracle變數
- SQL使用繫結變數,測試例項。SQL變數
- oracle bind value peeking繫結變數窺視Oracle變數
- SQL Server動態SQL,繫結變數SQLServer變數
- 繫結變數的測試變數
- 【效能優化】查詢繫結變數的sql語句優化變數SQL
- 【優化】使用繫結變數 OR 不使用繫結變數,這不是問題!優化變數
- SQL Developer中使用繫結變數SQLDeveloper變數
- 繫結變數及其優缺點變數
- PL/SQL中繫結變數使用的簡單測試SQL變數
- 關於繫結變數的SQL繫結什麼值變數SQL
- oracle繫結變數的測試Oracle變數
- 檢視未繫結變數的sql變數SQL
- 獲取sql繫結變數的值SQL變數
- 統計沒有繫結變數SQL變數SQL
- ORACLE優化實戰(繫結變數)Oracle優化變數
- 繫結變數變數
- 關於pl/sql中的繫結變數SQL變數
- [SQL]oracle 繫結變數(bind variable)[轉載]SQLOracle變數
- oracle 11g 新特性之動態繫結變數窺視(二)Oracle變數
- oracle 11g 新特性之動態繫結變數窺視(一)Oracle變數
- 繫結變數在靜態sql和動態sql中變數SQL
- Oracle 繫結變數Oracle變數
- 關於sql_profile中的繫結變數SQL變數
- 統計未用繫結變數的sql語句變數SQL
- oracle 查詢未使用繫結變數的sqlOracle變數SQL