7.3 批量查找

SQL

SELECT *
FROM Customers
WHERE CustomerID in (
    SELECT DISTINCT CustomerID 
    FROM Orders
    WHERE OrderDate>='2021-01-01' and OrderDate<='2021-12-31' and Amount>2000 )

SPL

等值查找时,常常需要进行批量查找,有时候可能多个值位于同一个索引段。为了避免重复读取相同的索引段,使用 contain 函数会自动对查找值排序,当查找下一个值时会先和上一个读取的索引段对比一下,能复用则复用,不能复用则抛弃再读下一个,提升效率。

A
1 >st=date(“2021-01-01”), et=date(“2021-12-31”), start=days@o(st), end=days@o(et)
2 =file(“Customers.ctx”).open()
3 =A2.index(file(“Orders.ctx__ids”);CustomerID)
4 =file(“Orders_Time.ctx”).open().cursor@mx(CustomerID;OrderDate>=start && OrderDate<=end && Amount>2000)
5 =A4.groups(CustomerID).(#1)
6 =A2.icursor(;A5.contain(CustomerID); file(“Orders.ctx__ids”)).fetch()
7 =A2.close()

当数据量很大时,索引经常也很大,需要建立多级索引,每次查找时都要一级一级地读入,才能最终定位到目标值。
有些索引要反复使用几百上千次,如果每次用到都重新加载,就会有明显延迟了。
SPL 提供自动缓存索引的机制, 已经使用过的索引会被缓存。在短时间内再次用到时就不会重复读取,能有效地减少查找延时。同时,SPL 还提供了主动预加载部分索引段的方法,系统启动时主动加载,之后的查找都会比较快,而不必等到这些索引段都被访问过。

SPL 主动预加载分级索引的代码:

A
1 =file(“Orders.ctx”).open()
2 =A1.index@3(file(“Orders.ctx__ids”))

A2 预加载组表 A1 的索引 idh 的前三级

加载多少级索引,取决于内存容量,一般来说,前三级索引可能会占用到约几个 G 的空间。

当组表文件是行存时,其创建的索引就是行存索引;当组表文件是列存时,其创建的索引就是列存索引。创建索引的代码和前面一样,这里不再赘述。
列存索引的查找性能要比行存差,它更适合用于遍历计算。当表的列数很多,而需要选出的列数非常少时,列存更有优势。
因此,在把数据转储成组表文件时,根据实际需要,选择行存或者列存。

当组表采用列存,同时又经常需要查找时,可以把常被选出的字段作为带值字段写进索引里,这样相当于索引表中不仅仅存储了索引字段和记录序号,还存了常被选出的这些字段。因此查找时如果只用到这些字段,就可以不访问原组表。这就相当于在行存数据中做查找,可以得到更好的性能。

带值索引的创建代码:

A
1 =file(“Customers.ctx”).open()
2 =A1.index(file(“Orders.ctx__ids”);CustomerID;CustomerName,City,Region)

A2 创建索引时,把 CustomerName,City,Region 这三个字段作为带值字段写进索引里,查找时如果只用到这三个字段,则不必读原组表