性能优化技巧——多层排号键

排号键是SPL独特的数据类型,适合替代多层次,各层不连续的键值,比如×××号,合同编号,产品编号,组织机构代码等。排号键定位速度快,常用于优化内存索引查询和外键关联计算。

内存索引查询

cardNormal.btx是集文件格式的×××信息表,数据量一百万条,字段为:cardNo(×××,主键),姓名(姓,名),性别(性别),省(省份),电子邮件(电子邮件),移动(移动电话),地址(住址).cardK.btx与cardNormal.btx在结构和数据上完全相同,唯一的区别在cardNo字于段是排号键。

本案例对cardNormal.btx和cardK.btx分别执行百万次索引查询,并比较两者性能。

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

位数12345678910111213141516规则行政区划生日流水校验细则省地区年月日流水校验范例100319801213023 x

省、地区:各自取值范围为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(中期(cardNo 1 2)),

int(中期(cardNo 3 2)),

间隔(“1980 - 06 - 01 -“,日期(中期(cardNo 5 8),“yyyyMMdd")),

int(中期(cardNo 13 3)))

下面对cardNormal.btx和cardK.btx分别执行百万次索引查询。


他们=cardNormal=文件(“d: \ \ temp \ \ cardNormal.btx") .import@b () . keys (cardNo) .index()/将cardNormal.btx读入内存2=paramList=cardNormal。(cardNo) .sort (rand()),(100000)/随机取1万个×××3


4=现在()

5 100=paramList。(cardNormal.find(~))/查询百万次6=interval@ms (A4,现在())
/字符串键性能:5537 ms7


8=cardK=文件(“d: \ \ temp \ \ cardk.btx") .import@b () . keys (cardNo) .index@s ()
/将cardK.btx读入内存9=paramListK=paramList。(k (int(中期(~ 1 2)),,int(中期(2 ~ 3)),间隔(“1980 - 06 - 01 -“,日期(中期(~ 5 8),“yyyyMMdd")),,int(中期(3 ~ 13))))
/将字符串参数转为排号键参数10=()

100年11=paramListK。(cardK.find(~))/查询百万次12=interval@ms (A10,现在())
/排号键性能:1977

A8女士:对排号键建立内存哈希索引,需使用函数选项@。

可以看的到,对字符串键建立索引,查询需耗费5547毫秒,而排号键只需1977毫秒,后者明显快。

,外键关联查询

taxNormal.btx是集文件格式的报税信息表,数据量一千万条,字段为:串行(主键,流水号),cardNo(外键,×××)、税务(报税额)、区域(所属地区),declaretype(申报类型),单位(申报单位),declareTime(申报时间),网络(办理网点).taxK。btx与taxNormal。btx在结构和数据上完全相同,唯一的区别在cardNo字于段是排号键。

本案例算法:

1只,,,,,,对taxNormal.btx和cardNormal。btx进行外键关联计算,排除操作系统缓存和硬盘IO的影响,只取关联动作消耗的时间。

2只,,,,,对taxK.btx和cardK。btx进行外键关联计算,排除操作系统缓存和硬盘IO的影响,只取关联动作消耗的时间。

3只,,,,,比较1和2的差异。

具体算法如下:


他们=文件(“d: \ \ temp \ \ taxNormal.btx") .cursor@b A1(), 10000/打开报税表,预遍历游标2=A1.reset ()
/重置游标到起点3=文件(“d: \ \ temp \ \ cardNormal.btx") .import@b () . keys (cardNo) .index ()
/打开×××表4=现在()

5 A1, 10000
/正式遍历游标6=interval@ms (A4,现在())=A1.reset()/遍历游标耗时3748 ms7=A1.switch (A1, cardNo) cardNo A3: 10000/建立关联,预遍历游标8=A1.reset ()
/重置游标到起点9=现在()

10 A7, 10000
/正式遍历关联游标11=interval@ms (A9,现在())=A11-A6/建立关联耗时:7553 ms12/上面:字符串键关联。下面:排号键关联

13=文件(“d: \ \ temp \ \ taxK.btx") .cursor@b()首次购物,10000/打开报税表,预遍历游标14=A13.reset ()
/重置游标到起点15=文件(“d: \ \ temp \ \ cardK.btx") .import@b () . keys (cardNo) .index@s ()
/打开×××表16=现在()

17 A13, 10000
/正式遍历游标18=interval@ms (A16,现在())=A13.reset()/遍历游标耗时2884 ms19=A13.switch A19 cardNo) (cardNo A15:, 10000/建立关联,预遍历游标20=A19.reset ()

性能优化技巧——多层排号键