DB2多表连接的三种方式

DB2 V9.7 for Linux, UNIX, and Windows

连接方法

当查询要求连接表时,优化器可以选择三种基本连接策略中的一种策略:嵌套循环连接(nested loop join)、合并连接(merge scan join)或散列连接(hash join)



嵌套循环连接(nested loop join)

嵌套循环连接通过下列两种方式中的一种方式执行:

  • 对于外表中每个被访问的行,扫描内表

    例如,表 T1 中的列 A 和表 T2 中的列 A 包含下列值:

外表 T1:列 A 内表 T2:列 A
2 3
3 2
3 2

3

1
  • 要在表 T1 与 T2 之间完成嵌套循环连接,数据库管理器将执行下列步骤:

    1. 读取 T1 中的第一行。A 的值是 2。

    2. 扫描 T2,直到找到匹配项(2)为止,然后连接这两行。

    3. 重复步骤 2,直到到达表的末尾为止。

    4. 返回至 T1 并读取下一行(3)。

    5. 从第一行开始扫描 T2,直到找到匹配项(3)为止,然后连接这两行。

    6. 重复步骤 5,直到到达表的末尾为止。

    7. 返回至 T1 并读取下一行(3)。

    8. 像前面那样扫描 T2,连接所有匹配的行(3)。

  • 对于外表中每个被访问的行,对内表执行索引查找

    如果存在以下格式的谓词,那么可以使用此方法:

       expr(outer_table.column) relop inner_table.column

    其中,relop 是比较运算符(例如 =、>、>=、< 或 <=),而 expr 是基于外表的有效表达式。例如:

       outer.c1 + outer.c2 <= inner.c1
       outer.c4 < inner.c3

    此方法可以显著减少每次访问外表时要在内表中访问的行数;受益程度取决于许多因素,其中包括连接谓词的选择性。

优化器对嵌套循环连接进行求值时,在执行连接前还将确定是否对外表进行排序。如果它根据连接列对外表进行排序,那么可以减少为了访问磁盘上的内表页而对内表执行读操作的次数,这是因为这些页很可能已在缓冲池中。如果该连接使用高度集群的索引来访问内表,并且外表已进行排序,那么所访问的索引页的数目可减至最少。

如果优化器预期该连接将执行成本更高的后期排序,那么它还可能选择在连接前执行排序。为了支持 GROUP BY、DISTINCT、ORDER BY 或合并连接操作,可能有必要执行后期排序。



合并连接(merge scan join)

合并连接(有时称为合并扫描连接排序合并连接)需要格式为 table1.column = table2.column 的谓词。这称为等式连接谓词。合并连接需要已排序的连接列输入,此排序可通过访问索引或执行排序实现。如果连接列是 LONG 字段列或大对象 (LOB) 列,那么无法使用合并连接。

在合并连接中,将同时扫描所连接的表。合并连接的外表只被扫描一次。除非外表中出现重复的值,否则内表也只被扫描一次。如果出现重复的值,那么可能再次扫描内表中的一组行。

例如,表 T1 中的列 A 和表 T2 中的列 A 包含下列值:

外表 T1:列 A 内表 T2:列 A
2
1
3 2
3 2

3

3

要在表 T1 与 T2 之间完成合并连接,数据库管理器将执行下列步骤:

  1. 读取 T1 中的第一行。A 的值是 2。

  2. 扫描 T2,直到找到匹配项(2)为止,然后连接这两行。

  3. 连续扫描 T2,当列匹配时,连接那些行。

  4. 当读取 T2 中的 3 时,返回至 T1 并读取下一行。

  5. T1 中的下一个值是 3,它与 T2 匹配,因此连接那些行。

  6. 连续扫描 T2,当列匹配时,连接那些行。

  7. 到达 T2 的末尾时,返回到 T1 以获取下一行。注意,T1 中的下一个值与 T1 中的上一个值相同,因此从 T2 中的第一个 3 开始再次扫描 T2。数据库管理器将记住此位置。



散列连接(hash join)

散列连接需要一个或多个格式为 table1.columnX = table2.columnY 的谓词,在此格式中,列类型相同。对于类型为 CHAR 的列,长度必须相同。对于类型为 DECIMAL 的列,精度和小数位必须相同。对于类型为 DECFLOAT 的列,精度必须相同。该列不能是 LONG 字段列或 LOB 列。

首先,扫描指定的内表并且将行复制到从排序堆中划出的内存缓冲区,该排序堆由 sortheap 数据库配置参数指定。根据使用连接谓词的列计算而得的散列值,将内存缓冲区分为若干部分。如果内表的大小超出可用的排序堆空间,那么将所选部分的缓冲区写入临时表。

处理内表完毕后,通过首先比较对连接谓词的列计算的散列值,扫描第二个表(外表)并将该表的行与内表的行匹配。如果外表行列的散列值与内表行列的散列值匹配,那么将比较实际的连接谓词列值。

与未被写入临时表的表部分相对应的外表行将立即与内存中的内表行匹配。如果内表的对应部分已被写入临时表,那么也将外表行写入临时表。最后,从临时表中读取匹配的表部分对,比较它们的行的散列值,然后检查连接谓词。

为了全面实现散列连接的性能增益,可能需要更改 sortheap 数据库配置参数和 sheapthres 数据库管理器配置参数的值。

如果能够避免散列循环以及溢出到磁盘,那么散列连接的性能最佳。要调整散列连接性能,请估算可供 sheapthres 使用的最大内存量,然后调整 sortheap参数。增大它的设置,尽可能避免散列循环和磁盘溢出,但不要达到 sheapthres 参数指定的限制。

增大 sortheap 值应该还能提高需要执行多次排序的查询的性能。



相关参考:
sheapthres -“排序堆阈值”配置参数

sortheap -“排序堆大小”配置参数



你可能感兴趣的:(DB2多表连接的三种方式)