排號鍵是SPL獨(dú)特的數(shù)據(jù)類型,適合替代多層次、各層不連續(xù)的鍵值,比如身份證號、合同編號、產(chǎn)品編號、組織機(jī)構(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是簡化后的身份證,格式如下:

省、地區(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)換腳本如下:

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

A8:對排號鍵建立內(nèi)存哈希索引,需使用函數(shù)選項@s。
可以看到,對字符串鍵建立索引,查詢需耗費(fèi)5547毫秒,而排號鍵只需1977毫秒,后者明顯快。
?外鍵關(guān)聯(lián)查詢
taxNormal.btx是集文件格式的報稅信息表,數(shù)據(jù)量一千萬條,字段為:serial(主鍵,流水號),cardNo(外鍵,身份證),tax(報稅額),area(所屬地區(qū)),declaretype(申報類型),unit(申報單位),declareTime(申報時間),network(辦理網(wǎng)點(diǎn))。taxK.btx 與taxNormal.btx在結(jié)構(gòu)和數(shù)據(jù)上完全相同,唯一的區(qū)別在于cardNo字段是排號鍵。
本案例算法:
1.?????? 對taxNormal.btx和cardNormal.btx進(jìn)行外鍵關(guān)聯(lián)計算,排除操作系統(tǒng)緩存和硬盤IO的影響,只取關(guān)聯(lián)動作消耗的時間。
2.?????? 對taxK.btx和cardK.btx進(jìn)行外鍵關(guān)聯(lián)計算,排除操作系統(tǒng)緩存和硬盤IO的影響,只取關(guān)聯(lián)動作消耗的時間。
3.?????? 比較1和2的差異。
具體算法如下:


B2、B7、B13、B19:預(yù)遍歷游標(biāo),避免操作系統(tǒng)緩存的影響。遍歷之后需用reset函數(shù)重置游標(biāo),以便后續(xù)再次遍歷。
B11、B23:用總時間減去遍歷時間,獲得關(guān)聯(lián)動作消耗的時間。
可以看到,用普通鍵做外鍵關(guān)聯(lián)計算,其關(guān)聯(lián)動作耗時7553ms;排號鍵做外鍵關(guān)聯(lián)計算時,只需耗時966ms,后者明顯快。而且可以看出,使用排號鍵讀出記錄(fetch)的時間也少于使用字符串(其它字段和記錄行數(shù)都相同),說明排號鍵對象的生成性能更好。