【12c】直方圖Histograms

直方圖,一種特殊類型的列的統計信息,它能提供表中列的更詳細的數據分佈信息,直方圖將值存放於桶(buckets)中。基於不一樣值的數目和數據的分佈,數據庫選擇要建立的直方圖類型,直方圖的類型有以下幾種:算法

  • 頻率直方圖和頂頻直方圖:Frequency histograms and to frequency histograms;
  • 高度平衡直方圖(遺留):Height-Balanced hitograms;
  • 混合柱狀圖:Hybrid histograms;

1 直方圖介紹

1.1 使用直方圖的目的

默認狀況下,優化器假定列的不一樣值之間時均勻分佈的。對於包含數據傾斜列(列中數據的分佈不均勻的列),直方圖使優化器可以爲涉及這些列的過濾或鏈接謂詞生成更準確的基數的估計值,從而生成更精確的執行計劃。sql

1.2 什麼時候數據庫建立直方圖

使用DBMS_STATS蒐集表的統計信息,查詢引用表中的列時,數據庫會根據以前的查詢負載來自動的建立直方圖。基本過程以下:數據庫

  • 使用DBMS_STATS蒐集表的統計信息,且指定METHOD_OPT參數默認爲SIZE AUTO;
  • 用戶查詢對應的表;
  • 數據庫記錄前面查詢時使用的謂詞,並更新數據字典表SYS.COL_USAGE$;
  • 再次運行DBMS_STATS時,DBMS_STATS會查詢SYS.COL_USAGE$視圖並根據前面的查詢負載決定哪些列須要直方圖。

示例:測試

1)建立測試表優化

SQL> create table sh.sales_new as select * from sh.sales;



Table created.

2)查看統計信息this

SQL> select column_name,notes,histogram from dba_tab_col_statistics where owner='SH' and table_name='SALES_NEW';



COLUMN_NAME NOTES HISTOGRAM

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

AMOUNT_SOLD STATS_ON_LOAD NONE

QUANTITY_SOLD STATS_ON_LOAD NONE

PROMO_ID STATS_ON_LOAD NONE

CHANNEL_ID STATS_ON_LOAD NONE

TIME_ID STATS_ON_LOAD NONE

CUST_ID STATS_ON_LOAD NONE

PROD_ID STATS_ON_LOAD NONE



7 rows selected.

3)執行查詢spa

SQL> select column_name,notes,histogram from dba_tab_col_statistics where owner='SH' and table_name='SALES_NEW';



COLUMN_NAME NOTES HISTOGRAM

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

AMOUNT_SOLD STATS_ON_LOAD NONE

QUANTITY_SOLD STATS_ON_LOAD NONE

PROMO_ID STATS_ON_LOAD NONE

CHANNEL_ID STATS_ON_LOAD NONE

TIME_ID STATS_ON_LOAD NONE

CUST_ID STATS_ON_LOAD NONE

PROD_ID STATS_ON_LOAD NONE



7 rows selected.

4)蒐集統計信息code

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS('SH','SALES_NEW',OPTIONS=>'GATHER AUTO');



PL/SQL procedure successfully completed.

5)查看統計信息blog

SQL> select column_name,notes,histogram from dba_tab_col_statistics where owner='SH' and table_name='SALES_NEW';



COLUMN_NAME NOTES HISTOGRAM

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

AMOUNT_SOLD STATS_ON_LOAD NONE

QUANTITY_SOLD STATS_ON_LOAD NONE

PROMO_ID STATS_ON_LOAD NONE

CHANNEL_ID STATS_ON_LOAD NONE

TIME_ID STATS_ON_LOAD NONE

CUST_ID STATS_ON_LOAD NONE

PROD_ID HISTOGRAM_ONLY FREQUENCY



7 rows selected.

6)查看列的使用it

SQL> select * from sys.col_usage$ where obj#=93264;



OBJ# INTCOL# EQUALITY_PREDS EQUIJOIN_PREDS NONEQUIJOIN_PREDS RANGE_PREDS LIKE_PREDS NULL_PREDS TIMESTAMP

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

93264 1 1 0 0 0 0 0 25-APR-20

1.3 如何選擇直方圖類型

前面講過,直方圖有多種類型,那麼建立直方圖時,數據庫如何選擇直方圖的類型呢?這裏有幾個參考變量:

  • NDV:表示列的不一樣值的數量;
  • n:表示直方圖桶(buckets)的數量,默認時254;
  • p:表示內部百分比閾值,等於(1-(1/n))*100;
  • DBMS_STATS中estimate_percent參數是否設置爲auto_sample_size(默認值)。

下圖展現的是直方圖建立時的決策樹:

 

2 直方圖基數算法

對於直方圖,基數的算法取決於端點數和值等因素,以及列值是否受歡迎。

2.1 端點編號和值(Endpoint Numbers and Values)

端點編號是惟一標識桶的編號,在頻率和混合直方圖中,端點編號是當前桶和以前桶中包含的全部值的累計頻率,例如:端點編號是100的桶表示當前桶和之前全部桶的值的總頻率是100,在高度平衡的直方圖中,優化器按順序給桶編號,從0或1開始。在全部狀況下,端點編號就是桶號。

端點值是桶中值範圍內的最大值,例如,若是一個桶只包含52794和52795,那麼端點值是52795。

2.2 受歡迎和不受歡迎值(Popular and Nopopular Values)

直方圖中某個值的受歡迎程度會影響基數估值算法,具體以下:

  • 受歡迎值:受歡迎值出如今多個桶的端點值,優化器經過檢查某個值是不是桶的端點值來肯定該值是否受歡迎,若是是,那麼對於頻率直方圖,優化器將從當前桶的端點數減去前一個桶的端點數,混合直方圖存儲了每一個端點的信息,若是這個值大於1,那麼該值是受歡迎的。對於受歡迎的值,優化器經過下面的公式計算基數估計:cardinality of popular value = (num of rows in table) * (num of endpoints spanned by this value / total num of endpoints);
  • 不受歡迎值:全部不是受歡迎的值都是不受歡迎的值,對於不受歡迎的值,,優化器經過下面的公式計算基數估計:cardinality of nonpopular value = (num of rows in table) * density。

2.3 桶壓縮(Bucket Compression)

在某些狀況下,爲了減小桶的總數,優化器將多個桶壓縮到一個桶中,例如,下面的頻率直方圖表示第一個桶數是1,最後一個桶數是23:

ENDPOINT_NUMBER ENDPOINT_VALUE 

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

            1             52792 

            6             52793 

            8             52794 

            9             52795 

            10            52796 

            12            52797 

            14            52798 

            23            52799

能夠看到,有幾個桶「丟失」了,最初,桶2到桶6每一個都包含一個值爲52793的實例,優化器將全部這些桶壓縮到具備最高端點數(桶6)的桶中,該桶如今包含5個實例的值52793,這個值是受歡迎的,由於當前桶和前一個桶的端點數之差爲5,所以,在壓縮以前,52793是5個桶的端點。下圖展現了哪些桶是壓縮的,哪些值是受歡迎的:

ENDPOINT_NUMBER ENDPOINT_VALUE 
--------------- -------------- 
        1                 52792 -> nonpopular 
        6                 52793 -> buckets 2-6 compressed into 6; popular 
        8                 52794 -> buckets 7-8 compressed into 8; popular 
        9                 52795 -> nonpopular 10 52796 -> nonpopular 
        12                52797 -> buckets 11-12 compressed into 12; popular 
        14                52798 -> buckets 13-14 compressed into 14; popular 
        23                52799 -> buckets 15-23 compressed into 23; popular

3 頻率直方圖

在頻率直方圖中,每一個不一樣的列值對應一個直方圖桶,因爲每一個值都有本身的專用桶,因此有些桶會有不少值,而有些則不多。

3.1 頻率直方圖知足的條件

當知足下面的條件時,數據庫建立頻率直方圖:

  • NDV少於或等於桶數(默認爲254);
  • DBMS_STATS對應的過程的參數設置爲AUTO_SAMPLE_SIZE或指定一個具體的值;

3.2 生成頻率直方圖

本實驗在sh.countries_new的列country_subregion_id產生頻率直方圖。

1)生成測試數據

SQL> create table sh.countries_new as select * from sh.countries;



Table created.



SQL> select country_subregion_id,count(1) from sh.countries_new group by country_subregion_id order by 1;



COUNTRY_SUBREGION_ID COUNT(1)

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

52792 1

52793 5

52794 2

52795 1

52796 1

52797 2

52798 2

52799 9



8 rows selected.

2)蒐集統計信息

begin

dbms_stats.gather_table_stats(ownname => 'SH',

tabname => 'COUNTRIES_NEW',

method_opt => 'for columns country_subregion_id');

end;

/



PL/SQL procedure successfully completed.

3)查看列統計信息

SQL> select column_name,notes,histogram from dba_tab_col_statistics where owner='SH' and table_name='COUNTRIES_NEW';



COLUMN_NAME NOTES HISTOGRAM

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

COUNTRY_NAME_HIST STATS_ON_LOAD NONE

COUNTRY_TOTAL_ID STATS_ON_LOAD NONE

COUNTRY_TOTAL STATS_ON_LOAD NONE

COUNTRY_REGION_ID STATS_ON_LOAD NONE

COUNTRY_REGION STATS_ON_LOAD NONE

COUNTRY_SUBREGION_ID FREQUENCY

COUNTRY_SUBREGION STATS_ON_LOAD NONE

COUNTRY_NAME STATS_ON_LOAD NONE

COUNTRY_ISO_CODE STATS_ON_LOAD NONE

COUNTRY_ID STATS_ON_LOAD NONE



10 rows selected.

可看到COUNTRY_SUBREGION_ID已蒐集了直方圖信息。

4)查看直方圖信息

select t.endpoint_number, t.endpoint_value

from dba_histograms t

where t.owner = 'SH'

and t.table_name = 'COUNTRIES_NEW'

and t.column_name = 'COUNTRY_SUBREGION_ID';



ENDPOINT_NUMBER ENDPOINT_VALUE

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

1 52792

6 52793

8 52794

9 52795

10 52796

12 52797

14 52798

23 52799



8 rows selected.

5)優化器評估52799的基數

SQL> select count(1) from sh.countries_new;



COUNT(1)

----------

23



SQL> select count(1) from sh.countries_new where country_subregion_id=52799;



COUNT(1)

----------

9

cardinality of popular value = (num of rows in table) * (num of endpoints spanned by this value / total num of endpoints)

即:C=23*(9/23)=9

和查詢的結果相同

4 最高頻率直方圖

最高頻率直方圖是頻率直方圖的一種變種,它忽略了統計上不重要的不受歡迎的值。

4.1 最高頻率直方圖知足的條件

若是一小部分值佔了大部分行,那麼在這一小部分值上建立一個頻率直方圖是頗有用的,即便NDV大於請求的直方圖的桶的數量。爲受歡迎的值建立一個更高質量的直方圖,優化器將忽略不受歡迎的值並建立一個直方圖。

當知足下面的條件時,數據庫建立最高頻率直方圖:

  • NDV大於直方圖桶的數量(默認爲254);
  • 前n個頻率值佔用的行數百分比等於或大於閾值p,p等於(1-(1/n))*100;
  • BMS_STATS對應的過程的參數設置爲AUTO_SAMPLE_SIZE;

4.2 生成最高頻率直方圖

本實驗在sh.countries_new的列country_subregion_id產生頻率直方圖。

1)生成測試數據

SQL> select country_subregion_id,count(1) from sh.countries_new group by country_subregion_id order by 1;



COUNTRY_SUBREGION_ID COUNT(1)

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

52792 1

52793 5

52794 2

52795 1

52796 1

52797 2

52798 2

52799 9



8 rows selected.

2)蒐集統計信息

begin

dbms_stats.gather_table_stats(ownname => 'SH',

tabname => 'COUNTRIES_NEW',

method_opt => 'for columns country_subregion_id size 7 ');

end;

/



PL/SQL procedure successfully completed.

3)查看列統計信息

SQL> select column_name,notes,histogram from dba_tab_col_statistics where owner='SH' and table_name='COUNTRIES_NEW';



COLUMN_NAME NOTES HISTOGRAM

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

COUNTRY_NAME_HIST STATS_ON_LOAD NONE

COUNTRY_TOTAL_ID STATS_ON_LOAD NONE

COUNTRY_TOTAL STATS_ON_LOAD NONE

COUNTRY_REGION_ID STATS_ON_LOAD NONE

COUNTRY_REGION STATS_ON_LOAD NONE

COUNTRY_SUBREGION_ID TOP-FREQUENCY

COUNTRY_SUBREGION STATS_ON_LOAD NONE

COUNTRY_NAME STATS_ON_LOAD NONE

COUNTRY_ISO_CODE STATS_ON_LOAD NONE

COUNTRY_ID STATS_ON_LOAD NONE



10 rows selected.

可看到COUNTRY_SUBREGION_ID已蒐集了最高頻率直方圖( TOP-FREQUENCY)信息。

4)查看直方圖信息

select t.endpoint_number, t.endpoint_value

from dba_histograms t

where t.owner = 'SH'

and t.table_name = 'COUNTRIES_NEW'

and t.column_name = 'COUNTRY_SUBREGION_ID';



ENDPOINT_NUMBER ENDPOINT_VALUE

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

1 52792

6 52793

8 52794

9 52796

11 52797

13 52798

22 52799



7 rows selected.

5 高度平衡直方圖(遺留)

在高度平衡直方圖中,將列值劃分爲桶,以便每一個桶包含大約相同的數據行。

 

待續。。。

相關文章
相關標籤/搜索