ComputeColStats UDF中 近似算法的介紹

一,前面的話算法

表和列的統計信息對CBO的結果有着極大地影響,可以高效和準確的收集統計信息是極其重要的。但高效和準確是矛盾的,更準確的統計信息每每須要更多的計算,咱們能作的是在高效和準確之間找到更好的平衡。接下來的內容是關於目前在ComputeColStats中用的一些近似算法。函數

二,收集的內容性能

目前針對列主要會收集如下統計信息:測試

cntRows : 列中總數據個數,包括nulll值ui

avgColLen :列的平均長度blog

maxColLEN :列的最大長度ci

minValue :列的最小值資源

maxValue :列的最大值get

numNulls :列中null值個數hash

numFalses :若是boolean型,false值的個數

numTrues :若是boolean型,true值的個數

countDistinct :不一樣值的個數

topK :topk值的個數,數據傾斜的標誌

通常說來除了countDistinct 和topK 之外的統計信息基本上消耗資源並不大(minValue和maxValue存在大量比較,也會消耗很多資源),問題主要集中在countDistinct 和topK上。下面要描述的近似算法也是主要針對這兩個點。

三,countDistinct 實現

算法:Flajolet-Martin

論文見:http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.81.3869&rep=rep1&type=pdf

簡介

對於n個object,若是Hash結果中,結尾(或開頭)連續0的長度的最大值是m,那麼,能夠估計惟一的object的數據量是2^m個。

假設有一個很是好的hash函數,可以將object哈希成一個二進制數0101……,而且很是均勻的打散到二進制空間。若是有8個惟一的object,將它們所有Hash以後,結果按照機率應該有4個object的Hash值以0結尾,這4個Hash值又應該有2個結尾是00,這2箇中又有1個結尾是000。

採用多個獨立的hash函數,每一個hash函數分別計算最長0比特序列,而後求平均值,減小偏差。

hash函數的個數基本上就決定了Flajolet-Martin算法的效率和準確度,後面有針對不一樣hash函數個數的測試結果。

四,topK實現

算法:Space-Saving

僞代碼:

五,基本性能測試

 

結論:

1,Base Stats對性能也是存在影響的,主要是minValue和maxValue的計算,尤爲是collen較長的狀況下

2,通常說來distinct相對topK會更慢些,除非在collen較長的時候,topK也是基於比較來的

3,隨着列個數的增長,收集stats消耗的時間也線性的增長

4,distinct的計算基於hash,而topK的計算基於比較,因此前者對collen並不敏感

 

六,不一樣hash函數個數執行效率的測試

 

結論:

基本上隨着hash函數個數的增長線性的增加

七,不一樣hash函數個數準確性的測試

 

 

結論:

hash函數個數增長到32個後,準確率基本能知足需求

八,不一樣hash函數個數的測試總結

 

 

結論:選擇32個hash函數計算distinct,平衡執行效率及準確性

九,sample算法的選擇

1,必要性:

基於前面對執行效率的測試,爲了不對任務產生過大的影響,Sample是必定要作的

2,Sample算法的要求:

效率,隨機

3,Sample的選擇:

採用buildin的sample函數實現

前提是假設數據分佈是隨機的

4,Sample的影響:

對某些stats基本沒影響,好比說avgColLen,maxColLen,minValue,maxValue

對某些stats有些影響,好比說cntRows, numNulls,numFalses,numTrues,topK

對countDistinct影響比較大,而且countDistinct也更加劇要,須要特別注意

5,Sample後countDistinct的處理:

根據Sample的countDistinct預測完整數據的countDistinct,採樣,擬合

基本思路以下圖:

但願經過對sample內的數據進行採樣,利用這些採樣點描繪所有數據的形態,達到基本準確預測所有數據distinct的結果。這是個美好的願望,在sample的數據相對較少的時候,總有些狀況下sample下的形態跟完整數據的形態存在較大的差別,此時的偏差會比較大。

十,不一樣sample比例執行效率的測試

 

採樣比例在1/100後執行時間差距不大,此時最大的消耗在數據讀取上,而不針對distinct的計算。

十一,不一樣sample比例準確性的測試

針對表meta.m_fuxi_instance表中的列project_name,odps_inst_id作了些測試,結果如上。看起來1/50的結果仍是能夠接受的。

多說一句,對於distinct來講,並不須要徹底的正確,10倍之內的差距目前來講是能夠接受的,這也是咱們能夠經過採樣來提升效率的前提。

十二,按sample比例爲1/25爲例的計算結果

執行時間和準確率基本均可以知足如今需求

十三,後續的工做

對於準確率的提高是後續須要作的事情之一,這關鍵仍是如何在sample裏面找帶更有表明性的點來預測所有數據的形態。但,要做好心理準備,對於某些場景來講,可能就找不到這樣的方法,須要接受必定範圍的偏差。

原文連接

閱讀更多幹貨好文,請關注掃描如下二維碼:

相關文章
相關標籤/搜索