oracle 查詢計劃中的基數cardinality概念(二)
執行計劃(2)-基數
執行計劃的cardinality列。基數是說從資料表,結果集或者索引返回多少行資料。
基數=錶行資料*選擇率。所以講基數重點是講選擇率,選擇率的計算!
版本10G 預設 表空間資訊:
TABLESPACE_NAME |
USERS |
BLOCK_SIZE |
8192 |
EXTENT_MANAGEMENT |
LOCAL |
ALLOCATION_TYPE |
SYSTEM |
SEGMENT_SPACE_MANAGEMENT |
AUTO |
DEF_TAB_COMPRESSION |
DISABLED |
BIGFILE |
NO |
比如我們建個表
Create table student ( id number,name varchar2(50),birday date,month_no number(2));
insert into student
select
trunc(dbms_random.value(1,1200)) id,
a.object_name,
sysdate-rownum as birday,
trunc(dbms_random.value(1,13)) month_no
from all_objects a
where rownum<=1200
分析下
SQL> analyze table student compute statistics;
看看資料分佈
select month_no ,count(1) from student group by month_no;
MONTH_NO |
COUNT(1) |
1 |
104 |
2 |
87 |
3 |
100 |
4 |
91 |
5 |
114 |
6 |
102 |
7 |
102 |
8 |
96 |
9 |
100 |
10 |
114 |
11 |
97 |
12 |
93 |
資料分佈得比較均勻
看看錶列的情況:
select * from user_tab_col_statistics where table_name='STUDENT'
TABLE_NAME |
COLUMN_NAME |
NUM_DISTINCT |
LOW_VALUE |
HIGH_VALUE |
DENSITY |
NUM_NULLS |
NUM_BUCKETS |
AVG_COL_LEN |
STUDENT |
ID |
762 |
C102 |
C20C61 |
0.00131233595800525 |
0 |
1 |
3 |
STUDENT |
NAME |
1192 |
41434345535324 |
5741524E494E475F53455454494E475324 |
0.000838926174496644 |
0 |
1 |
14 |
STUDENT |
BIRDAY |
1200 |
786C0C1F100D2E |
7870040D100D2E |
0.000833333333333333 |
0 |
1 |
7 |
STUDENT |
MONTH_NO |
12 |
C102 |
C10D |
0.0833333333333333 |
0 |
1 |
2 |
列名解釋:
1 NUM_DISTINCT 該列有多少個不同的值,非空.
2 LOW_VALUE 該列最小值
3 HIGH_VALUE 該列最大值
4 DENSITY 該列密度 如果有直方圖的話才有此值計算
5 NUM_NULLS 該列空置多少
6 NUM_BUCKETS 該列採用直方圖用多少桶
7 AVG_COL_LEN 該列平均長度
select * from user_tables where table_name='STUDENT'
AVG_ROW_LEN |
NUM_ROWS |
EMPTY_BLOCKS |
BLOCKS |
33 |
1200 |
3 |
13 |
表資訊: 分別是平均長度,資料行數,空塊數,全部塊數。
OK 我們把資料搞定了!接下來就可以談談選擇率了,看下這樣的語句的執行計劃。
SQL> set autotrace on
SQL> select count(*) from STUDENT where month_no=12;
COUNT(*)
----------
93
已用時間: 00: 00: 00.01
執行計劃
----------------------------------------------------------
Plan hash value: 4030891848
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 4 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | TABLE ACCESS FULL| STUDENT | 100 | 200 | 4 (0)| 00:00:01 |
------------------------------------------------------------------------------
SQLPLUS環境裡的ROWS就是基數
實際有93行而計劃裡說有100行,根據公式 基數=行數*選擇率。那麼選擇率=基數/行數 => ?=100/1200=1/12.
執行計劃是根據統計資訊來計算,來估算返回行的數量。
選擇率=1/ NUM_DISTINCT 或者是DENSITY 。 返回上面看看錶列的資訊中的值。這就是基本選擇率。
1 有空值情況下的選擇率
把每個月的生日置空10 共120.
update student set month_no =null where month_no=1 and rownum<=10;
…
update student set month_no =null where month_no=12 and rownum<=10;
再度分析下表,並檢視錶列資訊,可以看到month_no列NUM_NULLS=120
再次執行上面的語句得到執行計劃:
SQL> select count(*) from STUDENT where month_no=12;
COUNT(*)
----------
83
已用時間: 00: 00: 00.00
執行計劃
----------------------------------------------------------
Plan hash value: 403089184
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 4 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | TABLE ACCESS FULL| STUDENT | 90 | 180 | 4 (0)| 00:00:01 |
這裡的基數變成了90了
公式 選擇率=基本選擇率*(num_rows-num_nulls)/num_rows。
這裡的基本選擇率是1/num_distinct 因為使用了= 的條件。
公式推導 => ?=1/12*(1200-120)/1200=0.075
基數=1200*0.075 =90
2 使用列表 in(…)
1 回滾 update student set month_no=12 where month_no is null and rownum<=10;
2 分析表
3 檢視錶列資訊 發現NUM_NULLS 變回了0值。
4 執行語句:select count(*) from STUDENT where month_no in(6,7,8);
SQL> select count(*) from STUDENT where month_no in(6,7,8);
COUNT(*)
----------
300
已用時間: 00: 00: 00.00
執行計劃
----------------------------------------------------------
Plan hash value: 4030891848
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 4 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | TABLE ACCESS FULL| STUDENT | 300 | 600 | 4 (0)| 00:00:01 |
公式=基本選擇率+基本選擇率+基本選擇率= 3/12
如果in(15) or in(15,16) 基數分別 73,146 而不是100,200. 因為超過最大值,當超過最大與最小值距離(11) 為0.
距離15-12=3 間距12-1=11 平均遞減100/11=9.09 15的基數100-(3*9.09)=72.73=73。這說明ORACLE衰減思想。
3 區間謂詞的選擇率
1 month_no >8 ,>=8,<8,<=8
2 between 6 and 9
3 >=6 and <=9; >=6 and <9; >6 and <=9 ; >6 and <9
4 >12
5 between 25 and 30
6 >=:val1,> < <=:val1 繫結變數
7 >= :val1 and <= :val2 between :val1 and :val2
公式=需要空間除以可用空間
可用空間=high_vlaue-low_value=12-1=11
需要空間=(high_vlaue-limit) 或(limit-low_value)或(high_vlaue-low_value)
1 month_no>8 (high_vlaue-limit)/(high_vlaue-low_value)=(12-8)/11=4/11
2 month_no>=8 因為=是基本選擇率 1/12 因此 4/11+1/12
3 month_no < 8 小於用最小值 上面大於用最大值 (limit-low_value) /(high_vlaue-low_value)=(8-1)/11=7/11
4 between 6 and 9 or >=6 and <=9: (9-6)/(12-1)+1/12+1/12
5 (>=6,<9) (6>,<=9) :(9-6)/(12-1)+1/12
6 >6 and < 9 :(9-6)/(12-1)
7 >=:val1 固定選擇率5%
8 >=:val1 and <=:val2 固定比率 2.5%
9 超過範圍將逐步衰減。
4 雙謂詞
1 month >8 or month <=8
2 month >8 and month<=8
謂詞1的選擇率(12-8)/(12-1)=4/11=0.363636364
謂詞2的選擇率 (8-1)/(12-1)+1/12=7/11+1/12=0.71969697
公式 1 (謂詞1 AND 謂詞2)= 謂詞1選擇率*謂詞2的選擇率 因此第2個是 4/11*(7/11+1/12)= 0.261707989
公式 2 (謂詞1 or 謂詞2)= 謂詞1選擇率+謂詞2的選擇率-(謂詞1選擇率*謂詞2的選擇率)
=4/11+((7/11+1/12)-( 4/11*(7/11+1/12)))
=0.363636364+0.71969697- 0.261707989
=0.821625344
基數=1200*0.821625344=985.9504128=986
看下執行計劃:
SQL> select count(*) from student where month_no >8 or month_no<=8;
COUNT(*)
----------
1200
已用時間: 00: 00: 00.01
執行計劃
----------------------------------------------------------
Plan hash value: 4030891848
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 4 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
|* 2 | TABLE ACCESS FULL| STUDENT | 986 | 1972 | 4 (0)| 00:00:01 |
------------------------------------------------------------------------------
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28878983/viewspace-2136875/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle 查詢計劃中的基數cardinality概念(一)Oracle
- 查詢計劃中集的勢(Cardinality)的計算
- oracle中執行計劃中的cardinalityOracle
- oracle查詢語句執行計劃中的表消除Oracle
- 設計引數化查詢的計劃指南
- 基於UNION ALL的分頁查詢執行計劃問題(二)
- oracle cardinality對於執行計劃的影響Oracle
- 查詢oracle中的隱形引數Oracle
- oracle中基於ROWNUM的查詢的返回Oracle
- 統計Oracle 查詢事務數的方法Oracle
- MySQL中in(獨立子查詢)的執行計劃MySql
- CBO中基數(cardinality)、可選擇率(selectivity)的計算公式公式
- 16.基數(Cardinality)
- 使用計劃指南指定查詢引數化行為
- DB優化小常識 - 執行計劃中Cardinality的計算優化
- TiDB 查詢優化及調優系列(二)TiDB 查詢計劃簡介TiDB優化
- explain 查詢執行計劃AI
- 二叉查詢樹概念及實現
- 基於UNION ALL的分頁查詢執行計劃問題
- 基數反饋(Cardinality Feedback)
- Cardinality Feedback基數反饋
- HyperGraphDB查詢中的變數變數
- [oracle] 查詢歷史會話、歷史執行計劃Oracle會話
- 二維陣列中的查詢陣列
- Oracle 查詢事務數Oracle
- oracle 查詢所有表的行數Oracle
- Oracle隱含引數的查詢Oracle
- 二叉查詢樹的個數
- 計算查詢條件是or區間時候的selectivity和Cardinality
- oracle 索引升降序及排序條件 對查詢計劃的影響Oracle索引排序
- Mybatis中Oracle的拼接模糊查詢MyBatisOracle
- 【JZOF】二維陣列中的查詢陣列
- 查詢初始化引數的方法(二)
- FactorJoin: 一種新的連線查詢基數估計框架框架
- Oracle分頁查詢語句(二)Oracle
- 執行計劃-6:推入子查詢
- 對GPDB查詢計劃的Motion結點的理解
- 查詢數N二進位制中1的個數(JS版 和 Java版)JSJava