嵌套循环连接实现

Db2 for i 提供了 嵌套循环连接方法。 对于此方法,将对连接中的表进行排序处理。 此顺序称为 连接顺序。 最终连接顺序中的第一个表称为 主表。 其他表称为 辅助表。 每个连接表位置都称为 拨号

使用辅助表上的索引,散列表或辅助表上的表扫描 (到达顺序) 来实现嵌套循环。 通常,使用索引或散列表来实现连接。

索引嵌套循环连接实现

在连接期间, Db2 for i:

  1. 访问由主表的本地谓词选择的第一个主表行。
  2. 从主表中的连接列构建键值。
  3. 选择对第一个辅助表的访问权:
    • 如果使用索引,那么将使用 Radix Index Probe 来查找满足辅助表的连接条件的第一行。 探测器使用具有与辅助表的连接条件或本地行选择列匹配的键的索引。
    • 应用位图选择 (如果适用)。

      所有满足来自每个辅助拨号的连接条件的行都使用索引进行定位。 按随机顺序从辅助表中检索行。 此随机磁盘 I/O 时间通常占查询处理时间的很大百分比。 由于针对从主次拨号和前次拨号中选择的满足前次拨号的连接条件的每行搜索一次给定的次拨号,因此许多搜索可能针对后次拨号。 后期拨号处理中的任何效率低下都会显着增加查询处理时间。 这就是为什么关注连接查询的性能注意事项可以将连接查询的运行时间从几小时缩短到几分钟的原因。

      如果找不到有效的索引,那么可以创建临时索引。 某些连接查询会通过辅助拨号构建临时索引,即使存在所有连接键的索引也是如此。 由于效率对于运行时间较长的查询的辅助拨号很重要,因此优化器可以构建一个临时索引,其中仅包含具有该拨号的本地行选择的条目。 行选择的此预处理允许数据库管理器一次处理行选择,而不是每次行与拨号匹配时。

    • 如果使用散列表探测器,那么将创建一个散列临时结果表,其中包含针对第一个探测器上的表的本地选择中的所有行。 散列表的结构是将具有相同连接值的行装入到同一散列表分区 (集群) 中。 可以通过对连接值应用散列函数来找到任何给定连接值的行的位置。
      使用散列表探测器的嵌套循环连接与使用索引探测器的嵌套循环连接相比具有若干优点:
      • 散列临时结果表的结构比索引的结构更简单。 构建和探测散列表需要更少的 CPU 处理。
      • 散列结果表中的行包含查询所需的所有数据。 在探测散列表时,不需要使用随机 I/O 来访问表的数据空间。
      • 例如,连接值是集群的,因此通常可以使用单个 I/O 请求来访问给定连接值的所有匹配行。
      • 可以使用 SMP 并行性来构建散列临时结果表。
      • 与索引不同,不会为了反映下层表中列值的更改而更新散列表中的项。 散列表的存在不会影响系统中其它更新作业的处理成本。
    • 如果使用排序列表探测器,那么将创建一个排序列表结果,其中包含针对第一个探测器上的表的本地选择中的所有行。 排序列表表的结构使得具有相同连接值的行在列表中一起排序。 可以通过使用连接值进行探测来找到任何给定连接值的行的位置。
    • 如果使用 "表扫描" ,请找到满足辅助表的连接条件或本地行选择列的第一行。 当辅助表是用户定义的表函数时,可以使用表扫描来实现连接。
  4. 通过将任何剩余的选择应用于第一次辅助拨号,确定是否选择了该行。

    如果未选择辅助拨号行,那么将找到满足连接条件的下一行。 重复步骤 1 到 4 ,直到从所有辅助表中选择了同时满足连接条件和任何剩余选择的行

  5. 返回结果连接行。
  6. 再次处理最后一个辅助表以查找满足该拨号中的连接条件的下一行。

    在此处理期间,如果无法再选择满足连接条件的行,那么该处理将备份到逻辑上一个拨号。 它尝试读取满足其连接条件的下一行。

  7. 当处理主表中的所有选定行时结束处理。

请注意嵌套循环连接的以下特征:

  • 如果指定了排序或分组,并且所有列都在符合作为主表的条件的单个表上,那么优化器将花费与该表的连接作为主表,从而执行分组并使用索引进行排序。
  • 如果在两个或多个表上指定了排序和分组,或者如果允许临时对象,那么 Db2 for i 会将查询处理分为两个部分:
    1. 执行连接选择,省略排序或分组处理,并将结果行写入临时工作表。 此方法允许优化器将连接查询的任何表视为主表的候选项。
    2. 对临时工作表中的数据执行排序或分组。

无法使用散列连接的查询

散列连接不能用于下列查询:

  • 散列连接不能用于涉及具有读触发器的物理文件或表的查询。
  • 要求将游标位置复原为 SQL ROLLBACK HOLD 语句或 ROLLBACK CL 命令的结果。 对于使用除 *NONE 以外的落实控制级别的 SQL 应用程序,此方法要求将 *ALLREAD 指定为 ALWBLK 预编译器参数的值。
  • 不能将散列连接用于连接查询中除等于运算符以外的连接条件的表。
  • 如果查询包含以下任何一项,那么 CQE 不支持散列连接:
    • 子查询,除非查询中的所有子查询都可以转换为内部连接。
    • UNION 或 UNION ALL
    • 执行左外连接或异常连接的查询。
    • 使用 DDS 创建的连接逻辑文件的查询。