繫結變數的使用範圍
我們都知道繫結變數可以減少軟解析。
可是對於表的資料傾斜列,使用繫結變數有個壞處,那就是最佳化器可能會產生效能低下的執行計劃。
對於一個使用繫結變數的SQL語句,第一次執行的時候,最佳化器會使用一個叫做BIND PEEKING的技術,對繫結變數的值進行繫結窺探(BAND PEEKING),來生成執行計劃,以後再執行同樣的語句,會依賴於第一次執行時的執行計劃。
對於資料傾斜列,由於BIND PEEKING的特點,可能會產生效能非常低下的執行計劃。
下面看看測試情況:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
1)不使用繫結變數的情況。
測試表tab,其中列B為傾斜列。
SQL> desc tab;
名稱 是否為空? 型別
a number
b number
SQL> select b,count(1) from tab group by b;
B COUNT(1)
---------- ----------
1 1
2 1
3 1
4 1
5 9991
9996 1
9997 1
9998 1
9999 1
10000 1
可以看出列值等於5的佔了絕大數。
create index ind_tab_b on tab(b);
分析表:
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'SCOTT',
TABNAME => 'TAB',
CASCADE => TRUE);
END;
然後執行查詢:
SQL> select * from tab where b=1;
A B
---------- ----------
1 1
已用時間: 00: 00: 00.00
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
--------
SQL_ID 8vjf9k7jrfbh5, child number 0
-------------------------------------
select * from tab where b=:"SYS_B_0"
Plan hash value: 1668701379
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB | 1 | 6 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | SS | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("B"=:SYS_B_0)
已選擇19行。
已用時間: 00: 00: 00.17
SQL> select * from tab where b=5;
已用時間: 00: 00: 00.00
執行計劃
----------------------------------------------------------
Plan hash value: 1995730731
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9991 | 59946 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TAB | 9991 | 59946 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("B"=5)
可以看到產生了我們預想的正確的執行計劃。
[ 本帖最後由 wei-xh 於 2010-5-8 19:49 編輯 ]
可是對於表的資料傾斜列,使用繫結變數有個壞處,那就是最佳化器可能會產生效能低下的執行計劃。
對於一個使用繫結變數的SQL語句,第一次執行的時候,最佳化器會使用一個叫做BIND PEEKING的技術,對繫結變數的值進行繫結窺探(BAND PEEKING),來生成執行計劃,以後再執行同樣的語句,會依賴於第一次執行時的執行計劃。
對於資料傾斜列,由於BIND PEEKING的特點,可能會產生效能非常低下的執行計劃。
下面看看測試情況:
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
1)不使用繫結變數的情況。
測試表tab,其中列B為傾斜列。
SQL> desc tab;
名稱 是否為空? 型別
a number
b number
SQL> select b,count(1) from tab group by b;
B COUNT(1)
---------- ----------
1 1
2 1
3 1
4 1
5 9991
9996 1
9997 1
9998 1
9999 1
10000 1
可以看出列值等於5的佔了絕大數。
create index ind_tab_b on tab(b);
分析表:
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'SCOTT',
TABNAME => 'TAB',
CASCADE => TRUE);
END;
然後執行查詢:
SQL> select * from tab where b=1;
A B
---------- ----------
1 1
已用時間: 00: 00: 00.00
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
--------
SQL_ID 8vjf9k7jrfbh5, child number 0
-------------------------------------
select * from tab where b=:"SYS_B_0"
Plan hash value: 1668701379
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB | 1 | 6 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | SS | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("B"=:SYS_B_0)
已選擇19行。
已用時間: 00: 00: 00.17
SQL> select * from tab where b=5;
已用時間: 00: 00: 00.00
執行計劃
----------------------------------------------------------
Plan hash value: 1995730731
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9991 | 59946 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TAB | 9991 | 59946 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("B"=5)
可以看到產生了我們預想的正確的執行計劃。
[ 本帖最後由 wei-xh 於 2010-5-8 19:49 編輯 ]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-662254/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PLSQL使用繫結變數SQL變數
- 【優化】使用繫結變數 OR 不使用繫結變數,這不是問題!優化變數
- 關於繫結變數的使用變數
- 基礎 變數的作用範圍變數
- 【最佳化】使用繫結變數 OR 不使用繫結變數,這不是問題!變數
- 使用繫結變數的一點總結!變數
- PLSQL--變數範圍的討論SQL變數
- 繫結變數變數
- SQL Developer中使用繫結變數SQLDeveloper變數
- JavaScript變數 沒有塊範圍JavaScript變數
- PLSQL中使用繫結變數的語法SQL變數
- 繫結變數之繫結變數窺探(Bind Peeking)變數
- Oracle 繫結變數Oracle變數
- 【sql調優】使用繫結變數(二)SQL變數
- 【sql調優】使用繫結變數(一)SQL變數
- 繫結變數的測試變數
- C++ vector 元素數量變化不能使用範圍 forC++
- oracle 查詢未使用繫結變數的sqlOracle變數SQL
- 繫結變數窺測的演變變數
- 繫結變數優缺點、使用、繫結變數窺探、 Oracle自適應共享遊標變數Oracle
- oracle中使用繫結變數的好處的例子Oracle變數
- Perl中的變數作用範圍 local, my, our與全域性變數變數
- 如何在對in操作使用變數繫結(轉)變數
- 在繫結變數下使用outline變數
- java程式裡怎麼使用繫結變數Java變數
- SQL使用繫結變數,測試例項。SQL變數
- 檢視繫結變數變數
- 繫結變數窺測變數
- Oracle之繫結變數Oracle變數
- 關於繫結變數變數
- 關於繫結變數的SQL繫結什麼值變數SQL
- Javascript中變數範圍和hoist現象JavaScript變數
- SQL*Plus中使用DATE型別的繫結變數SQL型別變數
- 在oracle的plsql中為cursor使用繫結變數OracleSQL變數
- 查詢沒有使用繫結變數的sql zt變數SQL
- 繫結變數的一個例子變數
- oracle繫結變數的測試Oracle變數
- 查詢繫結變數的值變數