溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

性能優(yōu)化技巧 - 程序游標(biāo)

發(fā)布時(shí)間:2020-06-07 23:37:33 來(lái)源:網(wǎng)絡(luò) 閱讀:144 作者:raqsoft 欄目:大數(shù)據(jù)

很多算法都會(huì)產(chǎn)生落地的中間結(jié)果,從而影響性能,尤其是數(shù)據(jù)量較大的時(shí)候。這種情況下通??捎贸绦蛴螛?biāo)來(lái)避免數(shù)據(jù)落地,下面舉例說(shuō)明。

前半排序

計(jì)算目標(biāo):訂單表原來(lái)已按時(shí)間排序,需要將數(shù)據(jù)按日期、產(chǎn)品去除重復(fù),再統(tǒng)計(jì)記錄條數(shù)。

由于去重后結(jié)果集較大,內(nèi)存放不下,因此一般會(huì)用groupx去重,SPL腳本如下:


A
1=file("sales.btx").cursor@b()/從集文件讀入訂單記錄
2=A1.groupx(date(ORDERDATE),PRODUCTID)/按日期、產(chǎn)品分組去重
3=A2.skip()/對(duì)游標(biāo)計(jì)數(shù)

但函數(shù)groupx會(huì)導(dǎo)致數(shù)據(jù)落地,因此性能不高。

要使去重的中間結(jié)果不落地,可以先生成程序游標(biāo),distinctProduct.dfx腳本如下:


AB
1=file("sales.btx").cursor@b()
2for A1;date(ORDERDATE)=A2.id(PRODUCTID)
3
return B2

A2:循環(huán)訂單表。由于數(shù)據(jù)已按時(shí)間排序,因此每次取日期相同的一批數(shù)。

B2:按產(chǎn)品去重。注意,全量數(shù)據(jù)雖大,但按天取數(shù)相對(duì)較少,內(nèi)存可以放下,所以這里用id去重。

B3:返回本批次的去重結(jié)果。注意,程序游標(biāo)并非一次性返回所有數(shù)據(jù),而是每次循環(huán)之后,先等待調(diào)用者的請(qǐng)求,如果調(diào)用者繼續(xù)要數(shù)據(jù),程序游標(biāo)才會(huì)進(jìn)行下一次循環(huán),期間數(shù)據(jù)不落地。

主程序可通過(guò)cursor函數(shù)調(diào)用程序游標(biāo),用法與普通游標(biāo)類(lèi)似:


A
1=cursor("distinctProduct.dfx")/調(diào)用程序游標(biāo)
2=A1.skip()

         可以看到,程序游標(biāo)可減少數(shù)據(jù)落地,從而提升計(jì)算性能。

 集合運(yùn)算

數(shù)據(jù)庫(kù)進(jìn)行集合運(yùn)算時(shí)要先排序,如果數(shù)據(jù)量太大,則排序會(huì)耗費(fèi)大量時(shí)間,遲遲不能輸出結(jié)果。在這種情況下,適合用程序游標(biāo)生成不落地的有序中間結(jié)果集,從而實(shí)現(xiàn)快速輸出。

比如兩張結(jié)構(gòu)相同表:callRecordA、callRecordB。兩張表在時(shí)間字段callTime上建立了索引,每秒數(shù)據(jù)量萬(wàn)級(jí),現(xiàn)在對(duì)2015-01-01這一天的數(shù)據(jù)做并集運(yùn)算,需要快速輸出前500條(比如在報(bào)表上快速呈現(xiàn))。

這次將程序游標(biāo)和調(diào)用代碼寫(xiě)在同一個(gè)腳本中,如下:


ABC
1func=connect("orcl")
2
for 60*60*24=elapse(datetime("2015-01-01   00:00:00"),A2-1)
3

=A1.query("select   CALLTIME,OUTID,INID,DURATION,CHARGE from"+A1+"where callTime=?",B2)
4

=B3.sort(OUTID,INID,DURATION,CHARGE)
5

return B4
6
=A1.close()
7=cursor@c(A1,"callRecordA")
8=cursor@c(A1,"callRecordB")
9=[A7,A8].mergex@u()
10=A9.fetch@x(500)

A1:用func定義程序游標(biāo),相應(yīng)的調(diào)用語(yǔ)法為cursor@c。

B2:循環(huán)一天中的每一秒。

C3:從數(shù)據(jù)庫(kù)查詢(xún)一秒的數(shù)據(jù),因?yàn)槭前此饕?shù),所以速度很快,而且對(duì)數(shù)據(jù)庫(kù)影響很小。注意A1是表名變量,程序游標(biāo)既可以從callRecordA取數(shù),也可以從callRecordB取數(shù)。

C4:對(duì)一秒數(shù)據(jù)進(jìn)行內(nèi)存排序,以便形成有序結(jié)果集。由于數(shù)據(jù)在同一秒,所以只需對(duì)其他字段排序。

A7A8:以表名為參數(shù),取出2個(gè)程序游標(biāo)。

A9:對(duì)兩個(gè)游標(biāo)進(jìn)行有序歸并,@u表示取并集。類(lèi)似地,可以用@i和@d分別進(jìn)行并交集、差集運(yùn)算。


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI