我們知道,大資料運算效能的瓶頸常常是在外存(也就是硬碟)io上,因為外存訪問效能要比記憶體低一兩個數量級。因此,做效能優化時,減少硬碟的訪問量有時要比減少cpu計算量更為重要。同乙個任務,如果能使用硬碟訪問量更少的演算法,即使cpu計算量不變甚至略多一點,也會獲得更好的效能。
分組彙總需要對資料集進行遍歷。同乙個資料集可能會按不同維度進行分組,這樣原則上就要遍歷多次,大資料時就會涉及多遍硬碟訪問。但是,如果我們能在一次遍歷過程中計算出多個維度的分組結果,那就會減少很多硬碟訪問量。
可惜,sql無法寫出這樣的運算(在遍歷中返回多個分組結果),只能遍歷多次,或者寄希望於資料庫引擎是否能優化。而spl則支援這種遍歷復用的語法,可以一次遍歷計算出多個分組結果,從而提高效能。
下面我們做一下測試,以oracle為例看資料庫是否會對多次遍歷的計算進行優化,以及在spl中採用遍歷復用演算法對效能的影響。
spl指令碼生成資料檔案,資料共兩列,第一列id是小於20億的隨機整數,第二列amount是不大於1千萬的隨機實數。資料記錄為80億行,生成的原始文字檔案大小為169g。利用資料庫提供的資料匯入工具將此檔案資料匯入到oracle的資料表topn中,同時也用此檔案資料生成spl組表檔案topn.ctx。
在一台intel伺服器上完成測試,2個intel3014 cpu,主頻1.7g,共12核,記憶體64g。資料庫表資料及spl組表檔案均儲存在同一塊ssd硬碟上。
這裡刻意把資料量造得比記憶體大,以保證作業系統不可能把這些資料都快取進記憶體,實際運算時一定會讀取硬碟。
測試分成三種情況:單分組單倍計算量、單分組雙倍計算量、雙分組雙倍計算量。
select /*+ parallel(12) */ mod(id,100) aid,max(amount) amax from topn group by mod(id,100)
select /*+ parallel(12) */ mod(id,100)+floor(id/20000000) aid, max(amount) amax, min(amount) amin from topn group by mod(id,100)+floor(id/20000000);
計算式多了一倍,相當於計算量大了一倍。
select /*+ parallel(12) */ * from (select mod(id,100) aid,max(amount) amax from topn group by mod(id,100) ) a
join
( select floor(id/20000000) bid,min(amount) bmin from topn group by floor(id/20000000) ) b
on a.aid=b.bid;
這裡的計算量大體與2相同,但有兩個分組,我們將觀察資料庫是否會進行兩次遍歷。最後的join運算只涉及100行資料,時間可以忽略不計。
我們把oracle做的測試用spl再做一遍。
編寫spl指令碼執行測試:
編寫spl指令碼執行測試:
編寫spl指令碼執行測試:
這裡採用了spl特有的遍歷復用語法,在a3定義了游標,a4/b4和a5/b5中定義了兩套針對這個游標的計算,表示會在一次游標遍歷過程同時計算這兩個結果。
三種情況的測試用時如下表:
測試結果(時間單位:秒)
從oracle的測試結果上看,雙分組雙倍計算量比單分組雙倍計算量慢了近200秒,這不是乙個可以忽略的時間了,因為兩者的計算量幾乎相同,這多出來的時間估計就是多做一次遍歷的時間了。這說明資料庫不會自動做遍歷復用的優化,在雙分組時會將資料表遍歷兩次,結果多做一次分組幾乎會多出一倍的時間。
而spl採用了遍歷復用的機制,三個測試的計算時間相差很小,多做一次分組並不會多一次遍歷,只是多了一些復用控制的邏輯,不會變慢多少。
說明一下,準備資料時把oracle的amount欄位型別設定成decimal了,所以計算速度比較慢;而spl組表中用的是double型別,所以要快得多。但這個測試不是對比oracle和spl的計算效能,這些不同並不影響上面的結論。
jquery優化 遍歷
與使用選擇符查詢頁面中的元素相對應,jquery遍歷操作背後的工作機制也很有特色。了解了jquery對dom進行遍歷背後的工作機制,可以在編寫 時有意識地避免一些不必要的重複操作,從而提公升 的效能。本文就從jquery的遍歷機制入手簡單 一下優化jquery 的問題。jquery內部維護著乙個jq...
碰撞遍歷的優化
碰撞遍歷的優化 1,逐單位兩兩檢測,時間複雜度o n 2 只適用於少量單位檢測,效能隨著單位數量增加呈二次曲線下降 2,分階段檢測,broad phase和narrow phase,即粗篩和細篩 3,粗篩使用aabb檢測,不旋轉,簡單的整數加減,效能很高。快速篩選出可能碰撞單位進行細篩 4,narr...
fastJson順序遍歷JSON欄位
fastjson在把json格式的字串轉換成jsonobject的時候,使用的是hashmap,所以排序規則是根據hash值排序的,如果想要按照字串順序遍歷json屬性,需要在轉換的時候指定使用linkedhashmap代替hashmap。public static void main string...