3.6.2主键与索引表

为什么在集算器中,使用主键查找,会明显提升效率呢?这是由于在计算时,利用了主键的索引表来处理。

在调用keys函数,或者第一次在无索引的序表中执行基于主键的查找时,就会根据主键生成索引表。生成索引表时,会根据所有的主键值来生成哈希表,根据哈希值,将主键划分为很多组,而哈希值即为对应的组号。

在通常情况下,根据字段值在序表中查找某条记录时,需要逐条比较,直到发现目标记录为止。对于n条记录的序表,平均要比较n/2次。

而有了索引表,在根据主键字段的值,在序表中查找某条记录时,情况就不同了。首先,会根据主键的值计算哈希值,这样就可以根据它直接找到索引表中对应的组,然后只需要与同组的记录比较就可以了。同样对于n条记录的序表,如果序表的主键根据哈希值分布在k个组中,那么平均只需要比较n/2k次就可以了。这样的方法,虽然在生成索引表与执行查找前,付出了计算哈希值的代价,但是大大减少了比较的次数,尤其是索引表只需要生成1次就可以了。因此,在使用基于主键的查找函数时,序表中的数据量越大,需要查找的次数越多,对效率的提升就越明显。

在计算中,还可以用T.index(n)函数来主动为T的主键建立索引表,n为索引的长度。如果不设定,将使用默认的索引长度。

我们需要了解的是,用find,pfind等利用主键值查找的函数,可以有效地提升计算性能,是由于在序表中为主键建立索引表。因此,如果主键本身就可以作为索引定位记录时,就不必再去建立索引表了,如上面员工资料表中的EID字段,它本身就表示着记录在序表中的位置,用EID直接找到对应的记录效率会更高:

 

A

1

=demo.query("select * from EMPLOYEE").keys(EID)

2

=10000.(A1(rand(A1.len())+1).EID)

3

=now()

4

=A2.(A1(A2.~))

5

=interval@ms(A3,now())

6

=now()

7

=A2.(A1.find(A2.~))

8

=interval@ms(A6,now())

这一次,随机产生10000个员工编号来进行查找,A4中根据编号直接找到对应记录,A7中仍然使用find函数,A5A8中分别计算两种方法的耗时如下:

 

可以发现,用编号直接定位要快得多了,因为这种方法既不用比较字段值,也不必做哈希计算和建立索引表。而A4A7中查找到的结果是相同的:

可见,在集算器中,利用序表主键的索引功能提升效率时,要注意是否适用。