蛋疼的CBO等高直方圖演算法
--------------建立測試表
create table generator as
select
rownum id
from all_objects
where rownum <= 2000
;
create table t1 (
skew not null,
padding
)
as
select
/*+ ordered use_nl(v2) */
v1.id,
rpad('x',400)
from
generator v1,
generator v2
where
v1.id <= 80
and v2.id <= 80
and v2.id <= v1.id
order by
v2.id,v1.id;
;
create index t1_i1 on t1(skew);
select count(*) from t1;
COUNT(*)
----------
3240
-----------------產生等高直方圖
begin
dbms_stats.gather_table_stats(
user,
't1',
cascade => true,
estimate_percent => null,
method_opt => 'for all columns size 75'
);
end;
/
1)10G環境下
SQL> select
2 num_distinct, density, num_buckets
3 from
4 user_tab_columns
5 where
6 table_name = 'T1'
7 and column_name = 'SKEW'
8 ;
NUM_DISTINCT DENSITY NUM_BUCKETS
------------ ---------- -----------
80 .016563786 75
SQL> explain plan for
2 select * from t1 where skew=2;
已解釋。
SQL> select * from table(dbms_xplan.display);
------------------------------------------
| Id | Operation | Name | Rows |
------------------------------------------
| 0 | SELECT STATEMENT | | 54 |
|* 1 | TABLE ACCESS FULL| T1 | 54 |
------------------------------------------
由於查詢值2是個普通值,沒有橫跨任何桶,因此它的基數計算
=總行數*density=3240*0.016563786=54
可是11G後,不是這個演算法了,ORACLE從新算了一個新的density
11G下
explain plan for
select * from t1 where skew=2;
select * from table(dbms_xplan.display);
------------------------------------------
| Id | Operation | Name | Rows |
------------------------------------------
| 0 | SELECT STATEMENT | | 29 |
|* 1 | TABLE ACCESS FULL| T1 | 29 |
------------------------------------------
apollo@CRMG>select
2 num_distinct, density, num_buckets
3 from
4 user_tab_columns
5 where
6 table_name = 'T1'
7 and column_name = 'SKEW'
8 ;
NUM_DISTINCT DENSITY NUM_BUCKETS
------------ ---------- -----------
80 .013973812 75
按照原來的演算法=3240*0.013973812=45的。
從10053跟蹤後可以看到ORACLE做了調整,不知道依據什麼做出的調整。
哎。
---------------------10053內容
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for T1[T1]
Column (#1):
NewDensity:elect
num_distinct, density, num_buckets
from
user_tab_columns
where
table_name = 'T1'
and column_name = 'SKEW'
;
:q
.008958, OldDensity:0.013974 BktCnt:75, PopBktCnt:32, PopValCnt:16, NDV:80
Using density: 0.008958 of col #1 as selectivity of unpopular value pred
create table generator as
select
rownum id
from all_objects
where rownum <= 2000
;
create table t1 (
skew not null,
padding
)
as
select
/*+ ordered use_nl(v2) */
v1.id,
rpad('x',400)
from
generator v1,
generator v2
where
v1.id <= 80
and v2.id <= 80
and v2.id <= v1.id
order by
v2.id,v1.id;
;
create index t1_i1 on t1(skew);
select count(*) from t1;
COUNT(*)
----------
3240
-----------------產生等高直方圖
begin
dbms_stats.gather_table_stats(
user,
't1',
cascade => true,
estimate_percent => null,
method_opt => 'for all columns size 75'
);
end;
/
1)10G環境下
SQL> select
2 num_distinct, density, num_buckets
3 from
4 user_tab_columns
5 where
6 table_name = 'T1'
7 and column_name = 'SKEW'
8 ;
NUM_DISTINCT DENSITY NUM_BUCKETS
------------ ---------- -----------
80 .016563786 75
SQL> explain plan for
2 select * from t1 where skew=2;
已解釋。
SQL> select * from table(dbms_xplan.display);
------------------------------------------
| Id | Operation | Name | Rows |
------------------------------------------
| 0 | SELECT STATEMENT | | 54 |
|* 1 | TABLE ACCESS FULL| T1 | 54 |
------------------------------------------
由於查詢值2是個普通值,沒有橫跨任何桶,因此它的基數計算
=總行數*density=3240*0.016563786=54
可是11G後,不是這個演算法了,ORACLE從新算了一個新的density
11G下
explain plan for
select * from t1 where skew=2;
select * from table(dbms_xplan.display);
------------------------------------------
| Id | Operation | Name | Rows |
------------------------------------------
| 0 | SELECT STATEMENT | | 29 |
|* 1 | TABLE ACCESS FULL| T1 | 29 |
------------------------------------------
apollo@CRMG>select
2 num_distinct, density, num_buckets
3 from
4 user_tab_columns
5 where
6 table_name = 'T1'
7 and column_name = 'SKEW'
8 ;
NUM_DISTINCT DENSITY NUM_BUCKETS
------------ ---------- -----------
80 .013973812 75
按照原來的演算法=3240*0.013973812=45的。
從10053跟蹤後可以看到ORACLE做了調整,不知道依據什麼做出的調整。
哎。
---------------------10053內容
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for T1[T1]
Column (#1):
NewDensity:elect
num_distinct, density, num_buckets
from
user_tab_columns
where
table_name = 'T1'
and column_name = 'SKEW'
;
:q
.008958, OldDensity:0.013974 BktCnt:75, PopBktCnt:32, PopValCnt:16, NDV:80
Using density: 0.008958 of col #1 as selectivity of unpopular value pred
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-697852/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- dba_histograms等高直方圖和等頻直方圖的理解Histogram直方圖
- cbo心得(選擇率,基數,直方圖)(一)直方圖
- cbo心得(選擇率,基數,直方圖)(二)直方圖
- cbo心得(選擇率,基數,直方圖)(三)直方圖
- cbo心得(選擇率,基數,直方圖)(四)直方圖
- cbo心得(選擇率,基數,直方圖)(五)直方圖
- 【cbo計算公式】Frequenccy 直方圖選擇率(三)公式直方圖
- 【cbo計算公式】Height-balance直方圖選擇率(四)公式直方圖
- 直方圖直方圖
- 收集直方圖及檢視直方圖資訊直方圖
- cmake使用教程(六)-蛋疼的語法
- 直方圖(histograms)直方圖Histogram
- 7.3 直方圖直方圖
- oracle 直方圖Oracle直方圖
- 直方圖均衡化直方圖
- 04:垂直直方圖直方圖
- oracle直方圖使用Oracle直方圖
- 直方圖學習直方圖
- Oracle直方圖解析Oracle直方圖圖解
- [zt] Histograms - 直方圖Histogram直方圖
- 那些解釋起來很蛋疼的IT工種
- 影像演算法之直方圖均衡化(灰度影像)演算法直方圖
- [20170615]直方圖-高度直方圖(11g).txt直方圖
- windows 8.1 試用感受:蛋疼感大幅降低Windows
- ot 這個蛋疼的快取是怎麼回事快取
- 通過dbms_stats包修改統計資訊裡的最大值最小值,等頻等高直方圖直方圖
- 直方圖中最大矩形直方圖
- Oracle直方圖詳解Oracle直方圖
- 【效能優化】直方圖優化直方圖
- 聊一聊MySQL的直方圖MySql直方圖
- Python 編碼為什麼那麼蛋疼?Python
- [Python影象處理] 十一.灰度直方圖概念及OpenCV繪製直方圖Python直方圖OpenCV
- OpenCV計算機視覺學習(9)——影像直方圖 & 直方圖均衡化OpenCV計算機視覺直方圖
- 一文搞懂 Prometheus 的直方圖Prometheus直方圖
- oracle統計資訊--直方圖的收集:Oracle直方圖
- col_usage$與直方圖的收集直方圖
- halcon-直方圖均衡直方圖
- python如何畫直方圖Python直方圖