【性能优化】6.5 [外键关联] 内连接语法
6.5 内连接语法
我们知道,事实表的外键不一定总有对应的维表记录,有可能存在无效值。一种很常见的动作是:如果发现外键没有对应的维表记录,则删除这条事实表记录;如果有,则做地址化关联。这也就是内连接。
SPL 提供了针对游标的内连接语法:
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.groups(p_id.vendor;sum(p_id.price*quantity)) |
switch@i 将会把关联不上的事实表记录删除。
join 也有 @i 选项,意思是相同的。
switch@i 会先从游标中取出记录再判断关联,即使关联不上,这条记录也已经生成了。回顾第四章讲过的游标前过滤,要获得更好的性能,我们要在生成记录之前就完成关联判断。
SPL 对组表游标提供了这种机制:
A |
|
1 |
=file("product.btx").import@b().keys@i(id) |
2 |
=file("orders.ctx").open().cursor(p_id,quantity;p_id:A1) |
3 |
=A2.groups(p_id.vendor;sum(p_id.price*quantity)) |
在组表游标的过滤条件参数中可以写上关联关系,SPL 就会在生成记录之前判断能否关联上,如果可以则同时做地址化转换。
和 join 函数类似的原因,有多个关联字段时不能明确将哪个字段做地址化,也就不合适使用这种语法。SPL 提供了更通用的 fjoin 函数可以实现更丰富的地址化同时过滤的方案,不过这些内容已不涉及算法原理了,这里就不再详细解释了,有兴趣的读者可以参考 SPL 论坛上的资料。
如果只需要判断是否有关联,而不做外键地址化,则可以用常规的条件语法:
A |
|
1 |
=file("product.btx").import@b().keys@i(id) |
2 |
=file("orders.ctx").open().cursor(quantity;A1.find(p_id)) |
3 |
=A2.total(sum(quantity)) |
这时候有多个关联字段也可以处理。