溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

性能優(yōu)化技巧 - 多層排號鍵

發(fā)布時間:2020-08-16 02:56:13 來源:網(wǎng)絡 閱讀:185 作者:raqsoft 欄目:大數(shù)據(jù)

排號鍵是SPL獨特的數(shù)據(jù)類型,適合替代多層次、各層不連續(xù)的鍵值,比如×××號、合同編號、產(chǎn)品編號、組織機構(gòu)代碼等。排號鍵定位速度快,常用于優(yōu)化內(nèi)存索引查詢和外鍵關(guān)聯(lián)計算。

內(nèi)存索引查詢

cardNormal.btx是集文件格式的×××信息表,數(shù)據(jù)量一百萬條,字段為:cardNo(×××,主鍵),name(姓名),gender(性別),province(省份),email(電子郵件),mobile(移動電話),address(住址)。cardK.btx與cardNormal.btx在結(jié)構(gòu)和數(shù)據(jù)上完全相同,唯一的區(qū)別在于cardNo字段是排號鍵。

本案例對cardNormal.btx和cardK.btx分別執(zhí)行百萬次索引查詢,并比較兩者性能。

其中cardNo是簡化后的×××,格式如下:

位數(shù)12345678910111213141516
規(guī)則行政區(qū)劃生日流水校驗
細則地區(qū)流水校驗
范例100319801213023x

省、地區(qū):各自取值范圍為1-10。

生日:取值為"1980-06-01"至"1981-01-01"。

流水:取值為1-100。

校驗:根據(jù)前15位計算出的冗余校驗位,取值為0至10,其中10用x來表示。

將上述×××轉(zhuǎn)為排號鍵,可采取如下思路:

1.      省、地區(qū):排號鍵的每一層只支持1-255的整數(shù),因此將省和地區(qū)分別轉(zhuǎn)為整數(shù),作為第1、2層排號鍵。

2.      生日:排號鍵以1為起始,可以取得更好的性能,因此算出原生日和1980-06-01的間隔天數(shù),作為第3層排號鍵。

3.      流水:轉(zhuǎn)為整數(shù),作為第4層的排號鍵。

4.      校驗位:冗余數(shù)據(jù),可刪除。

具體轉(zhuǎn)換腳本如下:

k(int(mid(cardNo,1,2)),

int(mid(cardNo,3,2)),

interval("1980-06-01",date(mid(cardNo,5,8),"yyyyMMdd")),

int(mid(cardNo,13,3))

)

下面對cardNormal.btx和cardK.btx分別執(zhí)行百萬次索引查詢。


ABC
1=cardNormal=file("d:\\temp\\cardNormal.btx").import@b().keys(cardNo).index()/將cardNormal.btx讀入內(nèi)存
2=paramList=cardNormal.(cardNo).sort(rand()).to(100000)/隨機取1萬個×××
3


4=now()

5for 100=paramList.(cardNormal.find(~))/查詢百萬次
6=interval@ms(A4,now())
/字符串鍵性能:5537ms
7


8=cardK=file("d:\\temp\\cardk.btx").import@b().keys(cardNo).index@s()
/將cardk.btx讀入內(nèi)存
9=paramListK=paramList.(k(int(mid(~,1,2)),   int(mid(~,3,2)), interval("1980-06-01",date(mid(~,5,8),"yyyyMMdd")),   int(mid(~,13,3)) ))
/將字符串參數(shù)轉(zhuǎn)為排號鍵參數(shù)
10=now()

11for 100=paramListK.(cardK.find(~))/查詢百萬次
12=interval@ms(A10,now())
/排號鍵性能:1977ms

A8:對排號鍵建立內(nèi)存哈希索引,需使用函數(shù)選項@s。

可以看到,對字符串鍵建立索引,查詢需耗費5547毫秒,而排號鍵只需1977毫秒,后者明顯快。

 外鍵關(guān)聯(lián)查詢

taxNormal.btx是集文件格式的報稅信息表,數(shù)據(jù)量一千萬條,字段為:serial(主鍵,流水號),cardNo(外鍵,×××),tax(報稅額),area(所屬地區(qū)),declaretype(申報類型),unit(申報單位),declareTime(申報時間),network(辦理網(wǎng)點)。taxK.btx 與taxNormal.btx在結(jié)構(gòu)和數(shù)據(jù)上完全相同,唯一的區(qū)別在于cardNo字段是排號鍵。

本案例算法:

1.       對taxNormal.btx和cardNormal.btx進行外鍵關(guān)聯(lián)計算,排除操作系統(tǒng)緩存和硬盤IO的影響,只取關(guān)聯(lián)動作消耗的時間。

2.       對taxK.btx和cardK.btx進行外鍵關(guān)聯(lián)計算,排除操作系統(tǒng)緩存和硬盤IO的影響,只取關(guān)聯(lián)動作消耗的時間。

3.       比較1和2的差異。

具體算法如下:


ABC
1=file("d:\\temp\\taxNormal.btx").cursor@b()for A1,10000/打開報稅表,預遍歷游標
2=A1.reset()
/重置游標到起點
3=file("d:\\temp\\cardNormal.btx").import@b().keys(cardNo).index()
/打開×××表
4=now()

5for A1,10000
/正式遍歷游標
6=interval@ms(A4,now())=A1.reset()/遍歷游標耗時3748ms
7=A1.switch(cardNo,A3:cardNo)for A1,10000/建立關(guān)聯(lián),預遍歷游標
8=A1.reset()
/重置游標到起點
9=now()

10for A7,10000
/正式遍歷關(guān)聯(lián)游標
11=interval@ms(A9,now())=A11-A6/ 建立關(guān)聯(lián)耗時:7553ms
12/上面:字符串鍵關(guān)聯(lián)。下面:排號鍵關(guān)聯(lián)

13=file("d:\\temp\\taxK.btx").cursor@b()for A13,10000/打開報稅表,預遍歷游標
14=A13.reset()
/重置游標到起點
15=file("d:\\temp\\cardK.btx").import@b().keys(cardNo).index@s()
/打開×××表
16=now()

17for A13,10000
/正式遍歷游標
18=interval@ms(A16,now())=A13.reset()/遍歷游標耗時2884ms
19=A13.switch(cardNo,A15:cardNo)for A19,10000/建立關(guān)聯(lián),預遍歷游標
20=A19.reset()
/重置游標到起點
21=now()

22for A19,10000
/正式遍歷關(guān)聯(lián)游標
23=interval@ms(A21,now())=A23-A18/建立關(guān)聯(lián)耗時:966ms

B2、B7、B13、B19:預遍歷游標,避免操作系統(tǒng)緩存的影響。遍歷之后需用reset函數(shù)重置游標,以便后續(xù)再次遍歷。

B11、B23:用總時間減去遍歷時間,獲得關(guān)聯(lián)動作消耗的時間。

可以看到,用普通鍵做外鍵關(guān)聯(lián)計算,其關(guān)聯(lián)動作耗時7553ms;排號鍵做外鍵關(guān)聯(lián)計算時,只需耗時966ms,后者明顯快。而且可以看出,使用排號鍵讀出記錄(fetch)的時間也少于使用字符串(其它字段和記錄行數(shù)都相同),說明排號鍵對象的生成性能更好。


向AI問一下細節(jié)

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

AI