Db2 如何简化连接操作
Db2 有时可以简化连接操作,提高访问路径的效率。
入门概念
然而,由于完全外部连接的效率低于左连接或右连接,而左连接和右连接的效率又低于内部连接,因此建议在查询中尽量使用最简单的连接操作类型。
简化谓词,消除空值
Db2 当查询包含一个谓词或一个ON子句时,可以简化连接操作,从而消除连接操作产生的空值。- 消除空值的ON子句
请考虑下列查询:
SELECT * FROM T1 X FULL JOIN T2 Y ON X.C1=Y.C1 WHERE X.C2 > 12;外部连接操作生成以下结果表行:
- 在表 T1 和 T2 中, C1 的匹配值行(内连接结果)
- C1 在 T1 中不存在对应值的行 T2
- C1 在 T2 中不存在对应值的行 T1
然而,当您应用谓词时,您将删除结果表中所有来自 T2 的行,其中 C1 在 T1 中没有对应值。 Db2 将全连接转换为左连接,后者效率更高:
SELECT * FROM T1 X LEFT JOIN T2 Y ON X.C1=Y.C1 WHERE X.C2 > 12;- 消除空值的谓词
- 在下面的语句中,
X.C2>12谓词过滤掉了右连接产生的所有空值:SELECT * FROM T1 X RIGHT JOIN T2 Y ON X.C1=Y.C1 WHERE X.C2>12;因此, Db2 可以在不改变结果的情况下将正确的连接转换为更高效的内连接:
SELECT * FROM T1 X INNER JOIN T2 Y ON X.C1=Y.C1 WHERE X.C2>12; - 跟随连接操作的谓词
- 在 Db2 将外部连接转换为更简单的外部连接或内部连接之前,连接操作后的谓词必须具有以下特征:
- 谓词是布尔值术语谓词。
- 如果连接操作中有一个表的所有列都提供了空值,则谓词为假。
以下谓词是可能导致 Db2 简化连接操作的谓词示例:
T1.C1 > 10T1.C1 IS NOT NULLT1.C1 > 10 OR T1.C2 > 15T1.C1 > T2.C1T1.C1 IN (1,2,4)T1.C1 LIKE 'ABC%'T1.C1 BETWEEN 10 AND 10012 BETWEEN T1.C1 AND 100
- ON子句,用于消除不匹配的值
- 这个例子说明了 Db2 如何简化连接操作,因为查询包含一个ON子句,该子句会删除不匹配值的行:
SELECT * FROM T1 X LEFT JOIN T2 Y FULL JOIN T3 Z ON Y.C1=Z.C1 ON X.C1=Y.C1;因为最后一个ON子句会从结果表中删除任何列值来自 T1 或 T2 的行,所以 Db2 可以用更高效的左连接代替全连接,以获得相同的结果:
SELECT * FROM T1 X LEFT JOIN T2 Y LEFT JOIN T3 Z ON Y.C1=Z.C1 ON X.C1=Y.C1; - 全部外部连接按左外部连接处理
- 在一种情况下,当您无法编写代码时, Db2 会将完全外部连接转换为左连接。 这种情况是指视图指定了完全外部连接,但随后对该视图的查询只需要左外部连接。
例如,考虑一下以下语句所创建的视图:
CREATE VIEW V1 (C1,T1C2,T2C2) AS SELECT COALESCE(T1.C1, T2.C1), T1.C2, T2.C2 FROM T1 X FULL JOIN T2 Y ON T1.C1=T2.C1;此视图包含来自 T1 的 C2 值为空值的行。 但是,如果您执行以下查询,则可以删除 C2 中来自 T1:
SELECT * FROM V1 WHERE T1C2 > 10;因此,对于这个问题,在 T1 和 T2 之间进行左连接就足够了。 Db2 可以像使用左外连接生成视图 一样执行此查询,从而提高查询效率。 V1
删除左外连接中不需要的表
当SQL语句包含左外连接,但未从连接右侧选择任何列时, Db2 可以从语句中删除连接。
如果满足以下条件之一,则无需使用合适的桌子:
- 右表中的连接键列有一个唯一的索引。
- 语句指定了 SELECT DISTINCT。
例如,请考虑以下陈述:
SELECT DISTINCT T1.C3
FROM T1 LEFT OUTER JOIN T2
ON T1.C2 = T2.C2
WHERE T1.C1 = ?因为语句指定了 SELECT DISTINCT,所以不需要引用右表, Db2 可以为以下语句选择一条访问路径:
SELECT DISTINCT T1.C3
FROM T1
WHERE T1.C1 = ?因为语句中所有对正确表的引用都已删除,所以语句的PLAN_TABLE输出和访问路径图不再包含对表的引用。