排號鍵是spl獨特的資料型別,適合替代多層次、各層不連續的鍵值,比如身份證號、合同編號、產品編號、組織機構**等。排號鍵定位速度快,常用於優化記憶體索引查詢和外來鍵關聯計算。
cardnormal.btx是集檔案格式的身份證資訊表,資料量一百萬條,欄位為:cardno(身份證,主鍵),name(姓名),gender(性別),province(省份),email(電子郵件),mobile(移動**),address(住址)。cardk.btx與cardnormal.btx在結構和資料上完全相同,唯一的區別在於cardno欄位是排號鍵。
本案例對cardnormal.btx和cardk.btx分別執行百萬次索引查詢,並比較兩者效能。
其中cardno是簡化後的身份證,格式如下:位數1
2345
6789
1011
1213
1415
16規則
行政區劃
生日流水
校驗細則省地區
年月日流水
校驗範例10
0319
8012
1302
3x省、地區:各自取值範圍為1-10。
生日:取值為"1980-06-01"至"1981-01-01"。
流水:取值為1-100。
校驗:根據前15位計算出的冗餘校驗位,取值為0至10,其中10用x來表示。
將上述身份證轉為排號鍵,可採取如下思路:
1. 省、地區:排號鍵的每一層只支援1-255的整數,因此將省和地區分別轉為整數,作為第1、2層排號鍵。
2. 生日:排號鍵以1為起始,可以取得更好的效能,因此算出原生日和1980-06-01的間隔天數,作為第3層排號鍵。
3. 流水:轉為整數,作為第4層的排號鍵。
4. 校驗位:冗餘資料,可刪除。
具體轉換指令碼如下:
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分別執行百萬次索引查詢。ab
c1=cardnormal=file("d:\\temp\\cardnormal.btx").import@b().keys(cardno).index()
/將cardnormal.btx讀入記憶體
2=paramlist=cardnormal.(cardno).sort(rand()).to(100000)
/隨機取1萬個身份證34
=now()
5for 100
=paramlist.(cardnormal.find(~))
/查詢百萬次
6=interval@ms(a4,now())
/字串鍵效能:5537ms78
=cardk=file("d:\\temp\\cardk.btx").import@b().keys(cardno).index@s()
/將cardk.btx讀入記憶體
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)) ))
/將字串引數轉為排號鍵引數
10=now()
11for 100
=paramlistk.(cardk.find(~))
/查詢百萬次
12=interval@ms(a10,now())
/排號鍵效能:1977ms
a8:對排號鍵建立記憶體雜湊索引,需使用函式選項@s。
可以看到,對字串鍵建立索引,查詢需耗費5547毫秒,而排號鍵只需1977毫秒,後者明顯快。
taxnormal.btx是集檔案格式的報稅資訊表,資料量一千萬條,欄位為:serial(主鍵,流水號),cardno(外來鍵,身份證),tax(報稅額),area(所屬地區),declaretype(申報型別),unit(申報單位),declaretime(申報時間),network(辦理網點)。taxk.btx 與taxnormal.btx在結構和資料上完全相同,唯一的區別在於cardno欄位是排號鍵。
本案例演算法:
1. 對taxnormal.btx和cardnormal.btx進行外來鍵關聯計算,排除作業系統快取和硬碟io的影響,只取關聯動作消耗的時間。
2. 對taxk.btx和cardk.btx進行外來鍵關聯計算,排除作業系統快取和硬碟io的影響,只取關聯動作消耗的時間。
3. 比較1和2的差異。
具體演算法如下:ab
c1=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
/建立關聯,預遍歷游標
8=a1.reset()
/重置游標到起點
9=now()
10for a7,10000
/正式遍歷關聯游標
11=interval@ms(a9,now())
=a11-a6
/ 建立關聯耗時:7553ms
12/上面:字串鍵關聯。下面:排號鍵關聯
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
/建立關聯,預遍歷游標
20=a19.reset()
/重置游標到起點
21=now()
22for a19,10000
/正式遍歷關聯游標
23=interval@ms(a21,now())
=a23-a18
/建立關聯耗時:966ms
b2、b7、b13、b19:預遍歷游標,避免作業系統快取的影響。遍歷之後需用reset函式重置游標,以便後續再次遍歷。
b11、b23:用總時間減去遍歷時間,獲得關聯動作消耗的時間。
可以看到,用普通鍵做外來鍵關聯計算,其關聯動作耗時7553ms;排號鍵做外來鍵關聯計算時,只需耗時966ms,後者明顯快。而且可以看出,使用排號鍵讀出記錄(fetch)的時間也少於使用字串(其它欄位和記錄行數都相同),說明排號鍵物件的生成效能更好。
效能優化技巧 多層排號鍵
排號鍵是spl獨特的資料型別,適合替代多層次 各層不連續的鍵值,比如身份證號 合同編號 產品編號 組織機構 等。排號鍵定位速度快,常用於優化記憶體索引查詢和外來鍵關聯計算。記憶體索引查詢 cardnormal.btx是集檔案格式的身份證資訊表,資料量一百萬條,欄位為 cardno 身份證,主鍵 na...
效能優化技巧 多層排號鍵
排號鍵是spl獨特的資料型別,適合替代多層次 各層不連續的鍵值,比如身份證號 合同編號 產品編號 組織機構 等。排號鍵定位速度快,常用於優化記憶體索引查詢和外來鍵關聯計算。記憶體索引查詢 cardnormal.btx是集檔案格式的身份證資訊表,資料量一百萬條,欄位為 cardno 身份證,主鍵 na...
Oracle SQL 效能優化技巧
sun2004發表於 2008 12 25 11 28 眾所周知,資料庫設計的好壞直接關係到資料庫執行的效率。根據筆者的經驗,對於提公升資料庫效能來說,合理的資料庫設計,比公升級伺服器的硬體配置,還要來的有效。但是,筆者無論是在跟同事合作,又或者是在論壇上跟相關同行交流的時候,總是會發現有些人有一些...