ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 11G绑定变量情况下的选择率不再是5%?BUG?

11G绑定变量情况下的选择率不再是5%?BUG?

原创 Linux操作系统 作者:wei-xh 时间:2011-06-13 12:56:19 0 删除 编辑

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/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE组成员,DBGeeK用户组发起人。曾在DTCC、ORACLE技术嘉年华、Gdevops等公开场合做过数据库技术专题分享,2017年应Oracle邀请在世界最大的数据库会议OOW上做技术分享。组织翻译了《拨云见日,解密Oracle ASM内核》一书。

注册时间:2009-07-04

  • 博文量
    422
  • 访问量
    2340997