當(dāng)分組聚合的結(jié)果集不大時(shí),可以使用groups。例如有學(xué)生成績表存儲在集文件中,表結(jié)構(gòu)如下:

| Scores |
| class |
| studentID |
| subject |
| score |
| …… |
現(xiàn)在計(jì)算每個(gè)學(xué)生的總分?jǐn)?shù):
| A | |
| 1 | =file("scores.btx").import@b() |
| 2 | =A1.groups(studentID; ? sum(score):TotalScore) |
A1:成績表的數(shù)據(jù)裝入內(nèi)存。
A2:按照studentID字段分組,計(jì)算總分。
如果成績表數(shù)據(jù)太大,無法裝入內(nèi)存,則可以用游標(biāo)方式:
| A | |
| 1 | =file("scores.btx").cursor@b() |
| 2 | =A1.groups(studentID; ? sum(score):TotalScore) |
A1:得到成績表的游標(biāo)。
A2:按照studentID字段分組,計(jì)算總分。
當(dāng)成績表記錄很多,分組計(jì)算的結(jié)果集很大時(shí),就要使用groupx:
| A | |
| 1 | =file("scores.btx").cursor@b() |
| 2 | =A1.groupx(studentID; ? sum(score):TotalScore;10000) |
A1:得到成績表的游標(biāo)。
A2:按照studentID字段分組,計(jì)算總分。
groupx的最后一個(gè)參數(shù)是緩沖區(qū)行數(shù),也就是內(nèi)存里能夠一次處理的記錄條數(shù),這里指定為10000,實(shí)際使用時(shí)要根據(jù)自己的情況進(jìn)行調(diào)整。
當(dāng)數(shù)據(jù)對分組字段有序時(shí),可以使用groups@o。如上例中,當(dāng)成績表對studentID字段有序時(shí),就可以加上選項(xiàng)o:
| A | |
| 1 | =file("scores.btx").import@b() |
| 2 | =A1.groups@o(studentID; sum(score):TotalScore) |
如果成績表太大,無法裝入內(nèi)存,可以使用游標(biāo):
| A | |
| 1 | =file("scores.btx").cursor@b() |
| 2 | =A1.groups@o(studentID; sum(score):TotalScore) |
同樣,如果有序分組的結(jié)果集很大,就不能用groups,這時(shí)要使用group:
| A | |
| 1 | =file("scores.btx").cursor@b() |
| 2 | =A1.group(studentID; sum(score):TotalScore) |
group的返回是游標(biāo),這一點(diǎn)跟groups不一樣。
“后半”有序是指:要分組的表 T 已經(jīng)對字段a,b有序,現(xiàn)在我們要將表T按字段b進(jìn)行分組。例如有保存銷售記錄的集文件sale.btx,表結(jié)構(gòu)如下:
| Sales |
| date |
| employeeID |
| amount |
| …… |
銷售表對字段date,employeeID有序,現(xiàn)在要計(jì)算每個(gè)員工的銷售總額,對employeeID字段做分組,這時(shí)常規(guī)分組會計(jì)算hash,但這種后半有序的情況可以使用groups@h,看一下實(shí)現(xiàn):
| A | |
| 1 | =file("sale.btx").import@b() |
| 2 | =A1.groups@h(employeeID; ? sum(amount):TotalAmount) |
如果銷售表太大,無法裝入內(nèi)存,可以使用游標(biāo):
| A | |
| 1 | =file("sale.btx").cursor@b() |
| 2 | =A1.groups@h(employeeID; ? sum(amount):TotalAmount) |
當(dāng)分組表達(dá)式的結(jié)果是序號的時(shí)候,可以使用groups@n。仍然使用上例的銷售表,現(xiàn)在要計(jì)算統(tǒng)計(jì)每個(gè)月的銷售額,實(shí)現(xiàn)是這樣的:
| A | |
| 1 | =file("sale.btx").cursor@b() |
| 2 | =A1.groups@n0(month(date):MONTH;sum(amount): ? TotalAmount) |
A1:得到銷售表的游標(biāo)。
A2:把date字段轉(zhuǎn)換為月份,計(jì)算每個(gè)月的銷售總額;如果存在date字段是null的情況,則要加上選項(xiàng)@0。
使用@n之后,會依據(jù)序號去分組,而不用再計(jì)算HASH,所以要比不帶@n時(shí)快。
使用3億條數(shù)據(jù)測試,本案例實(shí)際測試結(jié)果:
| 耗時(shí)(秒) | |
| 有 @n | 沒有 @n |
| 39 | 49 |
過濾拆分是指根據(jù)條件分組,滿足條件和不滿足條件的分成兩個(gè)集。使用select可以做到這種拆分,但是要遍歷兩次,即一次select(條件true),和一次select(條件false)。
而使用group和align只需要遍歷一次。以上面成績表為例,現(xiàn)在要把成績及格的和不及格的分成兩組,看一下group的實(shí)現(xiàn):
| A | |
| 1 | =file("scores.btx").import@b() |
| 2 | =A1.group(score>=60) |
需要注意的是,使用group過濾拆分的結(jié)果不一定是兩個(gè)集,有可能結(jié)果只有一個(gè)集,如本例中,有可能出現(xiàn)成績都大于60的情況。這時(shí)候需要判斷一下結(jié)果集的個(gè)數(shù),或者使用align,因?yàn)閍lign的結(jié)果肯定是兩個(gè)集,沒有符合條件的記錄,也會產(chǎn)生一個(gè)空集。來看一下align的實(shí)現(xiàn):
| A | |
| 1 | =file("scores.btx").import@b() |
| 2 | =A1.align@a([true,false],score>=60) |
如果想在過濾拆分中把不滿足的寫進(jìn)文件,可以使用select(x;file),看一下實(shí)現(xiàn):
| A | |
| 1 | =file("scores.btx").cursor@b() |
| 2 | =A1.select (score>=60;file(“Fail.btx”)) |
| 3 | =A2.fetch() |
執(zhí)行完成后,A3里是成績及格的,不及格的會保存到集文件Fail.btx。
如果要拆分為多個(gè)集,可以使用groupn。例如要把成績分為優(yōu)秀、良好、及格和不及格這些集合,可以這樣實(shí)現(xiàn):
| A | |
| 1 | =file("scores.btx").cursor@b() |
| 2 | =[file(“Excellent.btx”), file(“Good.btx”), ? file(“Pass.btx”), file(“Fail.btx”)] |
| 3 | =A1.groupn(if(score>=90:1, ? score>=80:2, score>=60:3,4);A2) |
| 4 | =A3.fetch() |
top也可以用于group中,例如計(jì)算每個(gè)部門里薪水的大值:
| A | |
| 1 | =file("employee.btx").cursor@b() |
| 2 | =A1.groups(dept;top(-1,salary):MaxSalary) |
A1:得到員工表的游標(biāo)。
A2:按照dept字段分組,組內(nèi)再求最高薪水值,命名為topSalary。
A2執(zhí)行結(jié)果的MaxSalary字段是數(shù)值,如果想查詢薪水最高的員工的信息,可以寫成這樣:
| A | |
| 1 | =file("employee.btx").cursor@b() |
| 2 | =A1.groups(dept;top(-1;salary):MaxSalary) |
top不僅可以返回大值,還可以得到前n個(gè)最靠前的值,這時(shí)把1寫成n即可。例如計(jì)算每個(gè)部門里薪水排前三名的員工的信息:
| A | |
| 1 | =file("employee.btx").cursor@b() |
| 2 | =A1.groups(dept;top(-3;salary):topSalary) |
使用groups進(jìn)行分組計(jì)算時(shí),還可以采取并行方式進(jìn)一步提高性能,這時(shí)要加上選項(xiàng)@m。
如上面例中,計(jì)算每個(gè)員工的銷售總額,看一下并行方式的實(shí)現(xiàn):
| A | |
| 1 | =file("sale.btx").import@m() |
| 2 | =A1.groups@m(employeeID; sum(amount):TotalAmount) |
如果數(shù)據(jù)太大,無法裝入內(nèi)存,可以使用多路游標(biāo):
| A | |
| 1 | =file("sale.btx").cursor@mb() |
| 2 | =A1.groups@m(employeeID; sum(amount):TotalAmount) |
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
文章名稱:SPL分組優(yōu)化技巧-創(chuàng)新互聯(lián)
轉(zhuǎn)載注明:http://chinadenli.net/article30/cdodso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、ChatGPT、定制開發(fā)、網(wǎng)站建設(shè)、營銷型網(wǎng)站建設(shè)、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容