您好,登錄后才能下訂單哦!
關聯動作會嚴重影響性能,SPL支持內存預關聯,可以加快關聯動作,從而提升性能。
為了理解關聯動作對性能的影響,下面設計一套Oracle關聯表,以及無關聯的寬表,并執行同樣的計算。
關聯表的結構和關系如下:
數據量:通話記錄表(百萬條)、用戶表(十萬條)、開戶網點(一萬條),代理商表(一萬條)。
計算目標:求通訊總成本,即所有呼出用戶和呼入用戶分別對應的網點均攤成本、代理商均攤成本之和。
將關聯結果寫入另一張表,形成無關聯的寬表:
callRecordWide |
SERIALNUMBER |
CHARGE |
OUTBRANCHOUTCOST |
INBRANCHINCOST |
OUTAGENTOUTCOST |
INAGENTINCOST |
下面的SPL腳本,用來說明關聯動作對性能的影響:
A | B | |
1 | =connect("orcl") | |
2 | =now() | |
3 | for 10 | =A1.query("select sum(outBranch.outCost+inBranch.inCost+outAgent.outCost+inAgent.inCost) from callRecord,callUser outUser,callUser inUser,telecomBranch outBranch,telecomBranch inBranch,telecomAgent outAgent,telecomAgent inAgent where callRecord.outID=outUser.userID and callRecord.inID=inUser.userID and outUser.branchID=outBranch.branchID and outUser.agentID=outAgent.agentID and inUser.branchID=inBranch.branchID and inUser.agentID=inAgent.agentID") |
4 | =interval@ms(A2,now()) | /Oracle關聯表25802ms |
5 | ||
6 | =now() | |
7 | for 10 | =A1.query("select sum(outBranchOutCost+inBranchInCost+outAgentOutCost+inAgentInCost) from callRecordWide") |
8 | =interval@ms(A6,now()) | /oracle寬表2055ms |
9 | =A1.close() |
可以看到,關聯比無關聯慢12.6倍(25802/2055),會嚴重影響計算性能。
SPL可以通過預關聯來提升關聯動作的性能。首先加載數據到內存,代碼如下:
A | B | |
1 | =connect("orcl") | |
2 | =A1.query("select * from telecomAgent").keys(AGENTID) | |
3 | =A1.query("select * from telecomBranch").keys(BRANCHID) | |
4 | =A1.query("select * from callUser").keys(USERID) | |
5 | =A1.query("select * from callRecord").keys(SERIALNUMBER) | |
6 | =A1.switch(AGENTID,A2:AGENTID; BRANCHID,A3:BRANCHID) | |
7 | =A5.switch(OUTID,A14:USERID; INID,A4:USERID) | |
8 | =env(callRecord,A7) | /全局變量:預關聯 |
函數switch可將字段值替換為記錄引用,從而實現預關聯。
后續業務算法中,可以直接引用其他表的字段,從而提升關聯計算的性能,如下:
=callRecord.sum(OUTID.BRANCHID.OUTCOST+INID.BRANCHID.INCOST +OUTID.AGENTID.OUTCOST+INID.AGENTID.INCOST) |
為了直觀理解預關聯對計算性能的提升,下面同樣用SPL預關聯和寬表做比較。
A | B | |
11 | =connect("orcl") | |
12 | =A11.query("select * from telecomAgent").keys(AGENTID) | |
13 | =A11.query("select * from telecomBranch").keys(BRANCHID) | |
14 | =A11.query("select * from callUser").keys(USERID) | |
15 | =A11.query("select * from callRecord").keys(SERIALNUMBER) | |
16 | =A14.switch(AGENTID,A12:AGENTID; BRANCHID,A13:BRANCHID) | |
17 | =A15.switch(OUTID,A14:USERID; INID,A14:USERID) | |
18 | =env(callRecord,A17) | /全局變量:預關聯 |
19 | =A11.query@s("select * from callRecordWide").keys(SERIALNUMBER) | |
20 | =env(callRecordWide,A19) | /全局變量:寬表 |
21 | ||
22 | =now() | |
23 | for 10 | =callRecord.sum(OUTID.BRANCHID.OUTCOST +INID.BRANCHID.INCOST +OUTID.AGENTID.OUTCOST+INID.AGENTID.INCOST) |
24 | =interval@ms(A22,now()) | /SPL預關聯13272ms |
25 | ||
26 | =now() | |
27 | for 10 | =callRecordWide.sum(OUTBRANCHOUTCOST +INBRANCHINCOST+OUTAGENTOUTCOST +INAGENTINCOST) |
28 | =interval@ms(A26,now()) | /SPL寬表2210ms |
可以看到,預關聯比寬表慢6倍(13272/2210),相對于關聯表比寬表慢的12.6倍,已經有較大幅度的提升。在寬表時,SPL計算性能和ORACLE幾乎相同(2210:2055),但在有關聯時,預關聯的SPL計算速度已經明顯超出臨時關聯的ORACLE了(13272:25802)。
需要注意的是,上述算法雖然使用了寬表做對比,但并不是說寬表可以代替關聯表。事實上,寬表會浪費大量空間,還會造成創建、同步等維護困難,實際項目中很少用到。而預關聯使用引用來建立關聯,不會創造新表,不會浪費空間,不需要同步數據。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。