Oracle統計信息(三)—— 動態採樣(動態統計信息)與 多列統計信息

一、 動態採樣 Dynamic Sampling

1. 引入原因

oracle默認認爲where條件中出現的各列彼此是沒有關聯的,以此估算出的基數值可能不準,導致選錯執行計劃。

例如學生表有10000行,要查詢9月出生並且是處女座的人數,如果當作這兩個條件沒有關聯,默認的概率計算方法是(1/12) * (1/12) = 1/144,預估的返回值約爲69。但是顯然這兩個條件是有關聯的,9月出生的人大多都是處女座,實際返回行數應該遠大於69,而錯誤的基數預估,就可能導致選錯執行計劃。

爲了較準確地估算where條件中出現有關聯關係的列時所有條件組合的選擇率,進而得到較準確的基數值,9i R2版本引入了動態採樣技術。另外動態採樣可以在一定程度上解決因沒有統計信息而導致CBO選錯執行計劃的問題。

12c開始,該特性改名叫做 動態統計信息(Dynamic statistics)

 

2. 動態採樣原理

不同的應用、規則千差萬別,oracle如何能判斷各列間的關係,較準確地得出基數值?

其實,oracle在生成執行計劃前,採樣選取了表中部分數據塊,對採樣的數據塊實際執行了一次目標sql,這樣就能得到這部分數據塊的實際返回結果,而它又能通過數據字典查到表中總數據塊數,根據這個比例放大實際執行結果,這個結果就可以作爲目標sql較準確的基數值。

因此,只要目標表數據分佈相對均勻,oracle就能做到無論各列間有什麼關係,都能較準確地估算基數值。

注意,動態採樣僅適合單表或多表關聯的第一個驅動表的select,update,delete語句。如果對多表使用動態採樣,oracle無法判斷採樣哪些數據塊更有代表性,可能導致判斷錯上加錯。

 

3. 啓用方法

啓用方法有兩種:

  • 設置參數 optimizer_dynamic_sampling 的值>=1,10gR2以上版本默認值爲2,即默認是開啓的。
  • 使用動態採樣hint:dynamic_sampling(t,level),這裏的level對應上面的參數值。
select /*+ dynamic_sampling(t,2) */ * from t where n1=3 and n2=2 and c1='a'

optimizer_dynamic_sampling 參數值含義如下(以下參考自12.1文檔):

其中默認採樣數據塊數由_optimizer_dyn_smp_blks隱含參數控制,默認爲32。

Level 含義 默認採樣數據塊數 (Blocks)

0

不啓用

n/a

1

對沒有統計信息且滿足以下條件的表啓用

  • 語句中至少有一個非分區表沒有統計信息

  • 該表無索引

  • 該表數據塊數必須大於默認採樣塊數(即32)

32

2

默認值,對沒有統計信息的表啓用動態採樣

64

3

滿足以下任意條件時啓用:

  • 語句中至少有一個表沒有統計信息

  • where語句中使用了一個或多個表達式條件,例如 WHERE SUBSTR(CUSTLASTNAME,1,3)

64

4

滿足以下任意條件時啓用:

  • 語句中至少有一個表沒有統計信息

  • where語句中使用了一個或多個表達式條件,例如 WHERE SUBSTR(CUSTLASTNAME,1,3)

  • 單表查詢,且查詢條件中出現了至少兩列

64

5

The criteria are identical to level 4, but the database uses a different sample size.

128

6

The criteria are identical to level 4, but the database uses a different sample size.

256

7

The criteria are identical to level 4, but the database uses a different sample size.

512

8

The criteria are identical to level 4, but the database uses a different sample size.

1024

9

The criteria are identical to level 4, but the database uses a different sample size.

4086

10

The criteria are identical to level 4, but the database uses a different sample size.

All blocks

11

12c新增等級,在優化器認爲oracle需要動態採樣數據時自動收集

Automatically determined

 

二、 多列統計信息 MultiColumn Statistics

1. 簡介

實際上處理where條件中出現有關聯關係的列時不止一種解決方案,11g開始,oracle引入了多列統計信息,也稱爲組合列統計信息 Column Group Statistics。

11g開始,可以人爲指定存在關係的一組列爲目標表上的一個組合列,然後使用dbms_stats包對這個組合列收集統計信息,收集到的就是所謂多列統計信息。收集完成後,CBO自然也就知道了組合列的數據分佈情況。

 

2. 使用案例

創建cust_state_province和country_id列的Column Group

DECLARE
  cg_name varchar2(30);
BEGIN
  cg_name := dbms_stats.create_extended_stats(null,'customers','(cust_state_province,country_id)');
END;
/

查看column group name

select sys.dbms_stats.show_extended_stats_name('sh','customers','(cust_state_province,country_id)') col_group_name from dual;

COL_GROUP_NAME
--------------------------------------------------------------------------------
SYS_STU#S#WF25Z#QAHIHE#MOFFMM_

通過sys.col$基表可以看到,組合列其實就是在該表中多加了一列,列名爲column group name,類似oracle的函數索引。可以從dba_stat_extentions視圖中查詢目標表所有組合列信息。

--查詢多列統計信息
Select extension_name, extension from user_stat_extensions where table_name='CUSTOMERS';

EXTENSION_NAME                EXTENSION
------------------------------ ----------------------------------------
SYS_STU#S#WF25Z#QAHIHE#MOFFMM_   ("CUST_STATE_PROVINCE","COUNTRY_ID")

--查看distinct數和柱狀圖使用情況
select e.extension col_group, t.num_distinct, t.histogram
  from user_stat_extensions e, user_tab_col_statistics t
 where e.extension_name = t.column_name
   and e.table_name = t.table_name
   and t.table_name = 'CUSTOMERS';

COL_GROUP                              NUM_DISTINCT  HISTOGRAM
---------------------------------------- ------------ ---------------
("CUST_STATE_PROVINCE","COUNTRY_ID")           145  FREQUENCY

收集多列統計信息

--收集已存在的列組統計信息
EXEC DBMS_STATS.GATHER_TABLE_STATS('SH','CUSTOMERS',METHOD_OPT =>'FOR ALL COLUMNS SIZE AUTO');

--收集新指定的列組統計信息
EXEC DBMS_STATS.GATHER_TABLE_STATS('SH','CUSTOMERS',METHOD_OPT =>'FOR ALL COLUMNS SIZE SKEWONLY FOR COLUMNS (CUST_STATE_PROVINCE,COUNTRY_ID) SIZE SKEWONLY');

刪除Column Group

exec dbms_stats.drop_extended_stats('sh','customers','(cust_state_province,country_id)');

 

參考

https://docs.oracle.com/database/121/TGSQL/tgsql_astat.htm#TGSQL453

https://docs.oracle.com/database/121/REFRN/GUID-43655FC3-3C32-486B-8B11-8C20C152618D.htm#REFRN10140

http://blog.itpub.net/27126919/viewspace-1655727/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章