11G繫結變數情況下的選擇率不再是5%?BUG?
10G的時候
SQL> select * from v$version where rownum=1;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
SQL> select num_rows from user_tables where table_name='WXH_TBD1';
NUM_ROWS
----------
200000
explain plan for
select * from wxh_tbd1 where object_id>:a;
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------
Plan hash value: 1038246325
-----------------------------------------------
| Id | Operation | Name | Rows |
-----------------------------------------------
| 0 | SELECT STATEMENT | | 10000 |
|* 1 | TABLE ACCESS FULL| WXH_TBD1 | 10000 |
-----------------------------------------------
explain plan for
select * from wxh_tbd1 where object_id>:a and object_id<:b>
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------
Plan hash value: 1744766238
-----------------------------------------------
| Id | Operation | Name | Rows |
-----------------------------------------------
| 0 | SELECT STATEMENT | | 500 |
|* 1 | FILTER | | |
|* 2 | TABLE ACCESS FULL| WXH_TBD1 | 500 |
-----------------------------------------------
10G都是對的,開區間的時候,10000/200000=5%,閉區間的時候,500/200000=5%*5%,都是正確的。
看看11G
select * from v$version where rownum=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
select num_rows from user_tables where table_name='WXH_TBD';
NUM_ROWS
----------
19366
explain plan for
select * from wxh_tbd where object_id>:A;
Explained.
select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3295978849
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 966 | 89838 | 144 (3)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| WXH_TBD | 966 | 89838 | 144 (3)| 00:00:01 |
-----------------------------------------------------------------------------
966/19366=5%,是OK的。
explain plan for
select * from wxh_tbd where object_id>:A AND OBJECT_ID<:b>select * from table(dbms_xplan.display);
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 966 | 89838 | 144 (3)| 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | TABLE ACCESS FULL| WXH_TBD | 966 | 89838 | 144 (3)| 00:00:01 |
------------------------------------------------------------------------------
我們看到沒變化。
還是966.看來11G以後不管是開區間還是閉區間,都是預設的5%了,而不會像以前那樣相乘了。(都是繫結變數的情況)
select /*+ index(wxh_tbd) */ object_name from wxh_tbd where object_id > :a;
-------------------------------------------------------
| Id | Operation | Name | Rows |
-------------------------------------------------------
| 0 | SELECT STATEMENT | | 2492 |
| 1 | TABLE ACCESS BY INDEX ROWID| WXH_TBD | 2492 |
|* 2 | INDEX RANGE SCAN | PK_N | 449 |
-------------------------------------------------------
2 - access("OBJECT_ID">TO_NUMBER(:A))
最終表的選擇率是5%。2492/49842=5%.
可是索引的基數449不知道咋算的,沒查到資料,讓人摸不到頭腦,不按套路來
非繫結變數的情況下的選擇性和基數都是可以算出來的。我只是不知道這個開區間,繫結變數的情況下,索引如何去計算的這個選擇性和基數。
explain plan for select /*+ index(wxh_tbd1 T_1) */ object_name from wxh_tbd1 where object_id >12345;
select * from table(dbms_xplan.display);
--------------------------------------------------------
| Id | Operation | Name | Rows |
--------------------------------------------------------
| 0 | SELECT STATEMENT | | 17913 |
| 1 | TABLE ACCESS BY INDEX ROWID| WXH_TBD1 | 17913 |
|* 2 | INDEX RANGE SCAN | T_1 | 17913 |
--------------------------------------------------------
這種非繫結變數的情況,我是可以算出來的。
select min(object_id) from wxh_tbd1;
MIN(OBJECT_ID)
--------------
2
select max(object_id) from wxh_tbd1;
MAX(OBJECT_ID)
--------------
159398
select count(*) from wxh_tbd1;
COUNT(*)
----------
19463
SELECT column_name,NUM_NULLS FROM USER_TAB_COLS WHERE TABLE_NAME='WXH_TBD1' and column_name='OBJECT_ID';
COLUMN_NAME NUM_NULLS
-------------------- ----------
OBJECT_ID 47
選擇率=(最大值-開區間值)/最大值
基數=選擇率*總行數(非空)
select ((159398-12345)/159398)*(19463-47) FROM DUAL;
((159398-12345)/159398)*(19463-47)
----------------------------------
17912.2765
可以看到最後計算的結果跟ORACLE計算出來的是一樣的。
只是不知道開區間繫結變數的情況,ORACLE是怎麼計算的。
[ 本帖最後由 wei-xh 於 2011-6-13 10:04 編輯 ]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-697788/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從不繫結變數與繫結變數兩種情況討論柱狀圖的作用變數
- 繫結變數變數
- gorm使用事務併發情況下切有最大mysql連線數限制的情況下的BUG,踩坑了GoORMMySql
- 繫結變數之繫結變數窺探(Bind Peeking)變數
- Oracle 繫結變數Oracle變數
- 預算有限的情況下短影片開發公司的選擇很重要
- 在繫結變數下使用outline變數
- 繫結變數的測試變數
- 繫結變數窺測的演變變數
- BASH_SUBSHELL 變數不生效的情況變數
- switch-case選擇結構中的變數宣告變數
- 不重啟mysql情況修改引數變數MySql變數
- 檢視繫結變數變數
- 繫結變數窺測變數
- PLSQL使用繫結變數SQL變數
- Oracle之繫結變數Oracle變數
- 關於繫結變數變數
- 關於繫結變數的SQL繫結什麼值變數SQL
- 繫結變數的一個例子變數
- 繫結變數的使用範圍變數
- oracle繫結變數的測試Oracle變數
- 查詢繫結變數的值變數
- 關於繫結變數的使用變數
- 【優化】使用繫結變數 OR 不使用繫結變數,這不是問題!優化變數
- ORACLE 繫結變數用法總結Oracle變數
- 使用繫結變數的一點總結!變數
- 【最佳化】使用繫結變數 OR 不使用繫結變數,這不是問題!變數
- Oracle 變數繫結與變數窺視合集Oracle變數
- Oracle 繫結變數窺探Oracle變數
- oracle 繫結變數(bind variable)Oracle變數
- 如何獲取繫結變數變數
- Oracle 繫結變數 詳解Oracle變數
- 關於DSS中的繫結變數變數
- 檢視未繫結變數的sql變數SQL
- 獲取sql繫結變數的值SQL變數
- oracle 11g 新特性之動態繫結變數窺視(二)Oracle變數
- oracle 11g 新特性之動態繫結變數窺視(一)Oracle變數
- 11G R2 V$SQL_MONITOR檢視繫結變數SQL變數