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 这三个字段作为带值字段写进索引里,查找时如果只用到这三个字段,则不必读原组表