oracle cascade=>true,Oracle预估的基数算法

SQL> create table t as select * from dba_objects;

Table created.

SQL> create index idx_t on t(object_id);

Index created.

SQL> BEGIN

2 DBMS_STATS.GATHER_TABLE_STATS(ownname => 'TEST',

3 tabname => 'T',

4 estimate_percent => 100,

5 method_opt => 'for all columns size auto',

6 degree => DBMS_STATS.AUTO_DEGREE,

7 cascade => TRUE);

8 END;

9 /

SQL> alter session set optimizer_features_enable='9.2.0';

Session altered.

SQL> explain plan for select owner from t where object_id<1000;

Explained.

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------

Plan hash value: 1594971208

---------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

---------------------------------------------------------------------

| 0 | SELECT STATEMENT | |958 | 10538 | 26 |

| 1 | TABLE ACCESS BY INDEX ROWID| T |958 | 10538 | 26 |

|* 2 | INDEX RANGE SCAN | IDX_T |958 | | 4 |

---------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("OBJECT_ID"<1000)

Note

-----

- cpu costing is off (consider enabling it)

18 rows selected.

那么这个958 Oracle是怎么估算的呢?

Oracle预估的基数等于有效选择性*(num_rows-num_nulls)

其中 有效选择性 ,< 的有效选择性算法为:

(limit-low_value)/(high_value-low_value)

set linesize 200

SQL> select b.num_rows,

a.num_distinct,

a.num_nulls,

utl_raw.cast_to_number(high_value) high_value,

utl_raw.cast_to_number(low_value) low_value,

(b.num_rows - a.num_nulls) "NUM_ROWS-NUM_NULLS",

utl_raw.cast_to_number(high_value) -

utl_raw.cast_to_number(low_value) "HIGH_VALUE-LOW_VALUE"

from dba_tab_col_statistics a, dba_tables b

where a.owner = b.owner

and a.table_name = b.table_name

and a.owner = 'TEST'

and a.table_name = upper('T')

and a.column_name = 'OBJECT_ID'; 2 3 4 5 6 7 8 9 10 11 12 13 14

NUM_ROWS NUM_DISTINCT NUM_NULLS HIGH_VALUE LOW_VALUE NUM_ROWS-NUM_NULLS HIGH_VALUE-LOW_VALUE

---------- ------------ ---------- ---------- ---------- ------------------ --------------------

73964 73964 077085 2 73964 77083

那么估算为:

SQL>

select ceil((1000-2)/77083*73964) from dual;SQL>

CEIL((1000-2)/77083*73964)

--------------------------

958

Oracle 就是根据这个算法的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值