性能優化技巧:大事實表與大維表關聯

一、  問題背景與適用場景

在《性能優化技巧:小事實表與大維表關聯》中,我們嘗試了小事實表與大維表關聯時的性能優化方法,該方法利用了小事實表可以裝入內存的特點,將關聯鍵彙集排序後到大維表中查找,避免了遍歷大維表的動作。如果事實表與維表都大到不能裝載到內存時,這個辦法就不再有效了,那麼,還有什麼辦法提高性能呢?

SQL的方案是對兩個表做HASH分堆,拆小到內存可以放下的地步,分別寫入外存,然後再分別讀入進行內存關聯。如果運氣不好,拆出來的某個堆還是太大,就需要做二次HASH。同時,兩個表都需要做一遍HASH分堆動作,也就是需要把所有數據都緩存一遍。

如果維表是有序存放的,我們就可以將平均分段,由於有序存儲,所以可以計算出每一段值的邊界值,然後再用這個邊界值將事實表再分堆。這樣,維表本身由於有序存儲,可以直接按段讀取,而不需要再分堆;只有事實表被緩存出去,也就是隻有一個表被分堆緩存,所以這種辦法可以稱爲單邊方案。而且,由於維表可以被相對平均分段,不可能象HASH方法那樣出現運氣不好導致某堆太大的情況,一次分堆一定能解決問題,性能將得到保障。

SPL提供了這種關聯方法,下面我們實例測試一下,並且與使用HASH JOIN算法的Oracle對比。

 

二、  測試環境與任務

測試機有兩個Intel2670 CPU,主頻2.6G,共16核,內存64G,SSD固態硬盤。在此機上安裝虛擬機來測試,設置虛擬機爲16核、8G內存。

在虛擬機上創建維表account,共三個字段accountid、name、state,總記錄共10億行。創建事實表trade,總記錄共16億行,共四個字段tradedate、outid(轉出帳戶)、receiveid(接收帳戶)、amount(轉帳金額)。account表中的accountid是事實表中outid和receiveid的外鍵,都是一對多的關係。

在《性能優化技巧:小事實表與大維表關聯》中我們測試的是outid、receiveid兩個字段都要與account表中的accountid關聯,稱之爲雙維表。測試結果可見當事實表記錄數爲1500萬行時,Oracle運行時間已經接近5小時,而這次測試的事實表最少記錄數爲10億行,用Oracle運行的時間就會超過24小時了,所以測試只有outid關聯的情況,稱之爲單維表。測試任務爲查詢某段時期內各州轉出資金總額。

在SPL測試中,會用雙維表與單維表作對比測試。

爲縮短測試時間,全部採用4個並行。

三、  測試

1.  Oracle測試

編寫查詢測試SQL如下:

select    /*+ parallel(4) */

       state,

       sum(amount) as amount

from

       account,

       trade

where

       outid = accountid

       and tradedate >= date '2008-01-01' + interval '1500' day(4)

group by

       state

order by

       state;

其中/*+ parallel(4) */ 表示4個並行。

 

2.  SPL測試

編寫SPL腳本如下:

A
1 =now()
2 =elapse(date("2008-01-01"),1500)
3 =file(path+"account.ctx").create()
4 =file(path+"trade.ctx").create().cursor@m(outid,amount;tradedate>=A2;4)
5 =A4.joinx@u(outid,A3:accountid,state;4000000)
6 =A5.groups(state;sum(amount):amount)
7 =interval@s(A1,now())

joinx時加選項@u就適用於大事實表與大維表關聯,它的最後一個參數指明把遊標拆分爲多路時,每次從遊標中讀取的記錄數,在內存能裝下的情況下,此值越大性能越高。

 

3.  測試結果及分析

事實表不同數據量時的測試結果如下(單位:秒):

事實表過濾後記錄數 10億 12億 14億 15億 16億
Oracle 730 802 860 894 >10小時
SPL 486 562 643 681 730

經測算,10億行數據正常情況會超過8G內存,優秀的Oracle可能採用了數據壓縮技術,致使能裝下15億行數據。但是在16億行數據時,內存就怎麼也放不下了,開始發生大量佔用swap區的現象,也造成運行速度奇慢,測試中等了11小時也沒查詢出來,只好終止了。而SPL這種單邊技術,不受數據量大小的限制,本來就是面向外存設計,而且一次分堆就能解決,時間基本上呈線性增加。

 

四、  SPL雙維表與單維表對比測試

1.  單維表

編寫單維表測試SPL腳本如下:

A
1 =now()
2 =elapse(date("2008-01-01"),1500)
3 =file(path+"account.ctx").create()
4 =file(path+"trade.ctx").create().cursor@m(outid,receiveid,amount;tradedate>=A2;4)
5 =A4.joinx@u(outid,A3:accountid,state;4000000)
6 =A5.groups(state;sum(amount):amount)
7 =interval@s(A1,now())

 

2.  雙維表

編寫雙維表測試SPL腳本如下:

A
1 =now()
2 =elapse(date("2008-01-01"),1500)
3 =file(path+"account.ctx").create()
4 =file(path+"trade.ctx").create().cursor@m(outid,receiveid,amount;tradedate>=A2;4)
5 =A4.joinx@u(outid,A3:accountid,state:out_state;receiveid,A3:accountid,state:receive_state;4000000)
6 =A5.groups(out_state;sum(amount):amount)
7 =interval@s(A1,now())

 

3.  測試結果及分析

事實表不同數據量時的測試結果如下(單位:秒):

事實表過濾後記錄數 10億 12億 14億 16億
單維表 500 614 664 782
雙維表 1146 1375 1501 1957

雙維表比單維表多了一倍的關聯計算量,運算時間也僅僅略多於一倍,也是呈線性增加的,不會發生完全不可控的局面。


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