選擇率(selectivity)與基數(cardinality)
Oracle最佳化器要給出一個最優的執行計劃,應該也必須知道sql語句中所引用的底層物件的詳細資訊,其中比較重要的概念就是:選擇率和基數。
選擇率(selectivity)和基數(cardinality).官方文件如下:
SELECTIVITY:This measure represents a fraction of rows from a row set. The selectivity is tied to a query predicate, such as last_name='Smith', or a combination of predicates.
Cardinality:This measure represents the number of rows in a row set.
翻譯成中文:a)選擇率就是從一個行的集合中返回行數所佔的比率 b)基數就是從行集合中返回的預估行數
若相關表沒有直方圖,選擇率就簡單的等於DENSITY,cardinality基數=selectivity選擇率 * number of rows 表的行數,下面透過具體的實驗進行說明:
對錶收集統計資訊但不建立直方圖
由於上述表沒有收集直方圖,最佳化器無法知道列值的具體傾斜情況,因此選擇率就簡單的等於DENSITY(1/NUM_DISTINCT)。下面來檢視一下基數評估的情況:
基數評估為909,怎麼計算出來的呢。
選擇率=DENSITY=0.090909091,num of rows=10000,因此cardinality基數=10000*0.090909091=909
但實際情況呢?
表中skew=1的行數僅為1,評估的基數為909,為什麼會出現這種情況,因為skew列存在嚴重的傾斜,且表對該列也沒有收集直方圖,造成評估錯誤。下面對錶收集直方圖看看基數
可以看到,在收集直方圖後基數的評估為1,和實際情況相符。
只有統計資訊準確,資料庫才能生成理想的執行計劃。
選擇率(selectivity)和基數(cardinality).官方文件如下:
SELECTIVITY:This measure represents a fraction of rows from a row set. The selectivity is tied to a query predicate, such as last_name='Smith', or a combination of predicates.
Cardinality:This measure represents the number of rows in a row set.
翻譯成中文:a)選擇率就是從一個行的集合中返回行數所佔的比率 b)基數就是從行集合中返回的預估行數
若相關表沒有直方圖,選擇率就簡單的等於DENSITY,cardinality基數=selectivity選擇率 * number of rows 表的行數,下面透過具體的實驗進行說明:
點選(此處)摺疊或開啟
-
drop table t;
-
create table t as select rownum all_distinct,10000 skew from dual connect by level<=10000;
-
update t set skew=all_distinct where rownum<=10;
-
commit;
- select skew,count(*) from t group by skew order by skew;
-
SKEW COUNT(*)
---------- ----------
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
10000 9990
點選(此處)摺疊或開啟
- exec dbms_stats.gather_table_stats(USER,'T',method_opt=>'for all columns size 1');
-
SELECT COLUMN_NAME,NUM_DISTINCT,utl_raw.cast_to_number(LOW_VALUE),utl_raw.cast_to_number(HIGH_VALUE),DENSITY,NUM_NULLS FROM user_tab_col_statistics WHERE table_name='T';
COLUMN_NAME NUM_DISTINCT UTL_RAW.CAST_TO_NUMBER(LOW_VALUE) UTL_RAW.CAST_TO_NUMBER(HIGH_VALUE) DENSITY NUM_NULLS
--------------- ------------ --------------------------------- ---------------------------------- ---------- ----------
ALL_DISTINCT 10000 1 10000 .0001 0
SKEW 11 1 10000 .090909091 0
點選(此處)摺疊或開啟
-
explain plan for select * from t1 where skew=1;
-
SQL> SELECT * FROM table(dbms_xplan.display);
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
Plan hash value: 1601196873
-
-
--------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-
--------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 909 | 6363 | 7 (0)| 00:00:01 |
-
|* 1 | TABLE ACCESS FULL| T | 909 | 6363 | 7 (0)| 00:00:01 |
-
--------------------------------------------------------------------------
-
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
- 1 - filter("SKEW"=1)
選擇率=DENSITY=0.090909091,num of rows=10000,因此cardinality基數=10000*0.090909091=909
但實際情況呢?
點選(此處)摺疊或開啟
-
SQL> select count(*) from t where skew=1;
-
-
COUNT(*)
-
----------
- 1
點選(此處)摺疊或開啟
-
exec dbms_stats.gather_table_stats(user,'T',method_opt=>'for columns skew size 11');
-
SQL> explain plan for select * from t where skew=1;
-
-
Explained.
-
-
SQL> select * from table(dbms_xplan.display);
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
Plan hash value: 1601196873
-
-
--------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-
--------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 1 | 7 | 7 (0)| 00:00:01 |
-
|* 1 | TABLE ACCESS FULL| T | 1 | 7 | 7 (0)| 00:00:01 |
-
--------------------------------------------------------------------------
-
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
- 1 - filter("SKEW"=1)
可以看到,在收集直方圖後基數的評估為1,和實際情況相符。
只有統計資訊準確,資料庫才能生成理想的執行計劃。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29827284/viewspace-2134398/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- CBO中基數(cardinality)、可選擇率(selectivity)的計算公式公式
- PostgreSQL多值列的選擇性-Statistics,Cardinality,Selectivity,EstimateSQL
- cbo心得(選擇率,基數,直方圖)(一)直方圖
- cbo心得(選擇率,基數,直方圖)(二)直方圖
- cbo心得(選擇率,基數,直方圖)(三)直方圖
- cbo心得(選擇率,基數,直方圖)(四)直方圖
- cbo心得(選擇率,基數,直方圖)(五)直方圖
- oracle實驗記錄 (oracle單表選擇率與基數計算(1))Oracle
- oracle實驗記錄 (oracle單表選擇率與基數計算(2))Oracle
- oracle實驗記錄 (oracle單表選擇率與基數計算(3))Oracle
- 使用繫結變數窺探後的cardinality和selectivity的計算方法變數
- 16.基數(Cardinality)
- 基數反饋(Cardinality Feedback)
- Cardinality Feedback基數反饋
- 計算查詢條件是or區間時候的selectivity和Cardinality
- 直方圖、基數、選擇性、群集因子直方圖
- oracle實驗記錄 (選擇率)Oracle
- iOS倒數計時的探究與選擇iOS
- [20190827]函式索引與選擇率.txt函式索引
- oracle實驗記錄 (連線選擇率,範圍與null)OracleNull
- 基於CBO優化器謂詞選擇率的計算方法優化
- CSS ID選擇器與CLASS選擇器CSS
- MySQL數字型別int與tinyint、float與decimal如何選擇MySql型別Decimal
- 【cbo計算公式】Join 選擇率(六)公式
- 排序(2)--選擇排序,歸併排序和基數排序排序
- SQL 優化 概念篇 之 選擇性和基數SQL優化
- 基於CBO最佳化器謂詞選擇率的計算方法
- css 選擇器基礎CSS
- CSS基礎選擇器CSS
- oracle 查詢計劃中的基數cardinality概念(二)Oracle
- oracle 查詢計劃中的基數cardinality概念(一)Oracle
- 【cbo計算公式】單表選擇率(二)公式
- 數字化時代NAS儲存的誕生與選擇
- 特徵選擇(一)-維數問題與類內距離特徵
- Redis基礎篇(五)AOF與RDB比較和選擇策略Redis
- 11G繫結變數情況下的選擇率不再是5%?BUG?變數
- 【cbo計算公式】Frequenccy 直方圖選擇率(三)公式直方圖
- 數學基礎之機率