ComputeColStats UDF中 近似算法的介紹

一,前面的話

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

二,收集的內容

目前針對列主要會收集如下統計信息:
cntRows : 列中總數據個數,包括nulll值
avgColLen :列的平均長度
maxColLEN :列的最大長度
minValue :列的最小值
maxValue :列的最大值
numNulls :列中null值個數
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
僞代碼:
a01測試

五,基本性能測試

a02
結論:
1,Base Stats對性能也是存在影響的,主要是minValue和maxValue的計算,尤爲是collen較長的狀況下
2,通常說來distinct相對topK會更慢些,除非在collen較長的時候,topK也是基於比較來的
3,隨着列個數的增長,收集stats消耗的時間也線性的增長
4,distinct的計算基於hash,而topK的計算基於比較,因此前者對collen並不敏感ui

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

a03
結論:
基本上隨着hash函數個數的增長線性的增加spa

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

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

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

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

九,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,採樣,擬合資源

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

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

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

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

a08
針對表meta.m_fuxi_instance表中的列project_name,odps_inst_id作了些測試,結果如上。看起來1/50的結果仍是能夠接受的。
多說一句,對於distinct來講,並不須要徹底的正確,10倍之內的差距目前來講是能夠接受的,這也是咱們能夠經過採樣來提升效率的前提。

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

a09

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

十三,後續的工做

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

原文連接

相關文章
相關標籤/搜索