多表连接查询相对于单表查询更为复杂,它引入了连接操作。连接操作同样有可能存在性能问题。与前面章节中提到的优化方式相同,索引也是多表连接查询最主要的优化方式,其区别在于判断性能瓶颈的方式。接下来介绍连接操作的类型。
1.NESTED LOOP
NESTED LOOP适用于小数据量与大数据量的数据集之间的连接操作,NESTED LOOP被认为是性能最好的连接方式,在查询中也是最常用的。NESTED LOOP具体的业务逻辑类似下面的伪代码:
Foreach(SmallRow in SmallInput) { Foreach(BigRow in BigInput) { If(SmallRow=BigRow) Output; } }
在INNER JOIN的关联操作中,小数据集将作为外围循环数据集合,大数据集则作为内部循环的数据集合。假设Employee表(300条数据)与Person表(两万条数据)根据BusinessENtityId(高筛选率索引字段)进行连接,那么以NESTED LOOP的方式计算时,它的性能是最佳的。NESTED LOOP的I/O操作一般是小表的SCAN+大表的SEEK,或者都是索引的SEEK操作,也就是说,当内部表的字段上存在索引时NESTED LOOP的性能才会达到最佳,如图3-6所示。
2.MERGE JOIN
MERGE JOIN一般出现在连接数据集的数据量相当,并且数据集的连接条件均为顺序排列的情况下。其算法的伪代码大致如下:
R1=first row from Input1; R2=first row from Input2; While (end of Input 1) and (end of Input2) { If (R1=R2) { Output; R2=next row of Input2; } Else if (R1<R2) R1=next row of Input1; Else R2=next row of Input2; }
如果MERGE JOIN涉及的数据集不是已经排序的结果,将额外多出一部分排序操作,或者是HASH JOIN方式的操作。MERGE JOIN分为一对多和多对多的连接操作方式,当关联一方的字段上存在唯一索引时,将优先选择一对多的连接操作,效率比多对多的操作方式更高。
3.HASH JOIN
HASH JOIN应用在大数据量的连接中,它通过SCAN操作,将两份大的数据集取出,并对关联字段进行hash计算,从而得出两个集合的hash数据集。然后,将两份hash集合进行比较,并输出hash值相等的数据行。HASH JOIN数据集的获取操作大部分为SCAN操作。
HASH JOIN的伪代码示例如下:
Foreach(R1 in Input1) { H1=HashValue(R1.Key); Insert H1 into HashBucket; } Foreach(R2 in Input2) { H2=HashValue(R2.Key); Foreach(H1 in HashBucket) { If(H1=H2) Output(R1,R2); } }
如算法伪代码所示,当Input1的量为小数量集时,HASH JOIN的效率会比较高。当两个比较集合的数据量都很大时,HASH JOIN的效率会比较低。