【性能优化】6.6 [外键关联] 索引复用

 

【性能优化】6.5 [外键关联] 内连接语法

6.6 索引复用

有时候维表会被先过滤再做关联。比如我们只关心某个产地的产品:


A

1

=file("product.btx").import@b().keys@i(id)

2

=file("orders.btx").cursor@b(p_id,quantity)

3

=A2.switch@i(p_id,A1)

4

=A3.select(p_id.state=="CA")

5

=A4.groups(p_id.vendor;sum(p_id.price*quantity))

这样的计算量会比较大,A4 的判断要反复地取出 p_id.state 来判断,如果维表 A1 先被过滤,只剩下需要的记录,那么在 A3 的 switch@i 中就会把事实表中不合适的记录过滤掉,性能就会更好了。


A

1

=file("product.btx").import@b().select(state=="CA")

2

=file("orders.btx").cursor@b(p_id,quantity)

3

=A2.switch@i(p_id,A1)

4

=A3.groups(p_id.vendor;sum(p_id.price*quantity))

这段代码的计算量就要比前一段小很多。

但问题是,维表被过滤后成为一个排列后,它原来的索引就不能用了。switch 时会重建一个索引,而建索引也是需要时间的,需要计算主键的哈希值等等,在记录数比较多时建索引时间也不小,而且因为过滤条件不可预测,这个索引也不能事先准备。

其实,原表上的索引还是可以用的,至少哈希值不用重新计算,只要把过滤掉的记录从索引表中删除。SPL 提供了这种机制:


A

1

=file("product.btx").import@b().keys@i(id)

2

=file("orders.btx").cursor@b(p_id,quantity)

3

=A1.select@i(state=="CA")

4

=A2.switch@i(p_id,A3)

5

=A4.groups(p_id.vendor;sum(p_id.price*quantity))

select@i 将在过滤后的排列上复用原表的索引。

索引复用并不会总是更快,因为要把过滤掉的记录从索引表删除,如果过滤掉的记录数很多(剩下的较少),这个动作也不会很快。而剩下记录较少时,重建索引很可能更快。具体采用哪种方式,要根据实际情况决定。

【性能优化】6.7 [外键关联] 对位序列
【性能优化】 前言及目录