JOIN是关系数据库中常用运算,用于把多个表进行关联,关联条件一般是判断某个关联字段的值是否相等。随着关联表的增多或者关联条件越来越复杂,无论理解查询含义、实现查询语句,还是在查询的性能方面,可以说JOIN都是最具挑战的SQL运算,没有之一。
特别是JOIN的性能,一直是个老大难问题。下面我们将基于数据计算中间件(DCM)——集算器,来提供一些提升运算性能的方法。
当然,我们不是介绍如何在写SQL语句时怎么写JOIN,也就是我们假设已经对查询需求有了正确的理解并且能正确地实现SQL。这种情况下,要提升性能,就必须从最基本的提升数据IO配合算法及并行等手段做起。正因如此,如果数据仍然存储在数据库中,那也没什么好办法提速,因为数据库的IO效率很低,又几乎无法并行,即使把运算写得再精巧也无济于事。所以,要提高性能,一定要把数据搬出数据库,我们下面的讨论都是基于这个思路,而集算器正是实现这个思路的利器,甚至神器!
把数据表搬出数据库存储到集算器的集文件中很简单,只要用两行代码:
A |
|
1 |
=db.cursor("select * from 订单表") |
2 |
=file("Order.btx").export@b(A1) |
这两行代码把数据库里订单表的数据导出到集文件Order.btx。
因为数据库IO性能不佳,而且数据量也可能很大,所以这个“搬家”动作可能时间也不短,但还好是一次性的。后面我们的计算都将从集文件中取数。
1 判断 JOIN 的类型
在将数据搬出数据库后,我们需要首先判断JOIN的类型,然后才能采取有针对性的优化措施。
JOIN运算大家都很熟悉,按照SQL的语法定义划分,包括INNER JOIN(内连接)、LEFT JOIN(左连接)、RIGHT JOIN(右连接)、FULL JOIN(全连接)几个类型,这是根据在运算中对空值的处理规则进行划分的。而我们的分析和优化,则会从更贴近需求的语义角度出发,根据各个表的主键参与关联的情况进行划分,总体来说有这么三种:外键表、同维表、主子表。
外键表
当表A的某些字段与表B的主键关联,B称为A的外键表,A表中与B表主键关联的字段称为A指向B的外键。此时A表也称为事实表,B表也称为维表。
表A:Order订单表 |
|
ID |
订单编号 |
CustomerID |
客户编号 |
SellerID |
销售编号 |
OrderDate |
订购日期 |
Amount |
订单金额 |
表B:Customer客户表 |
|
ID |
客户编号 |
Name |
客户名称 |
Area |
所在区域 |
表C:seller销售人员表 |
|
ID |
员工编号 |
Name | <