5.11连接分解
在称为联接分解的基于成本的转换中,优化器可以分解UNION ALL查询分支中的常见计算。
5.11.1连接分解的目的
UNION ALL 查询在数据库应用程序中很常见,尤其是在数据集成应用程序中。
通常,UNION ALL查询中的分支引用相同的基表。如果没有UNION ALL联接分解,优化器将独立评估查询的每个分支,从而导致重复处理,包括数据访问和联接。
联接分解转换可以在UNION ALL分支之间共享通用计算。避免对大的基表进行额外的扫描可以极大地提高性能。
5.11.2联接分解如何工作
连接分解可以分解多个表中的两个以上的UNION ALL分支。
通过示例可以最好地解释联接分解。
示例5-11 UNION ALL查询
下面的查询显示的四个表(查询t1,t2,t3,和t4)和两个UNION ALL分支:
SELECT t1.c1, t2.c2
FROM t1, t2, t3
WHERE t1.c1 = t2.c1
AND t1.c1 > 1
AND t2.c2 = 2
AND t2.c2 = t3.c2
UNION ALL
SELECT t1.c1, t2.c2
FROM t1, t2, t4
WHERE t1.c1 = t2.c1
AND t1.c1 > 1
AND t2.c3 = t4.c3
在前面的查询中,table t1出现在两个UNION ALL分支中,过滤谓词t1.c1 > 1和join谓词也出现在两个分支中t1.c1 = t2.c1。未经任何转换,数据库必须对表执行t1两次扫描和筛选,每个分支一次。
示例5-12因式查询
SELECT t1.c1, VW_JF_1.item_2
FROM t1, (SELECT t2.c1 item_1, t2.c2 item_2
FROM t2, t3
WHERE t2.c2 = t3.c2
AND t2.c2 = 2
UNION ALL
SELECT t2.c1 item_1, t2.c2 item_2
FROM t2, t4
WHERE t2.c3 = t4.c3) VW_JF_1
WHERE t1.c1 = VW_JF_1.item_1
AND t1.c1 > 1
在这种情况下,由于表t1已分解,因此数据库仅执行一次表扫描和过滤t1。如果t1很大,则该分解避免了t1两次扫描和过滤的巨大性能成本。
注意:
如果UNION ALL查询中的分支具有使用该 DISTINCT 函数的子句,则联接分解无效。
5.11.3分解和联接顺序:方案
联接分解可以为联接订单创造更多可能性
示例5-13涉及五个表的查询
在以下查询中,视图V与示例5-11中的查询相同:
SELECT *
FROM t5, (SELECT t1.c1, t2.c2
FROM t1, t2, t3
WHERE t1.c1 = t2.c1
AND t1.c1 > 1
AND t2.c2 = 2
AND t2.c2 = t3.c2
UNION ALL
SELECT t1.c1, t2.c2
FROM t1, t2, t4
WHERE t1.c1 = t2.c1
AND t1.c1 > 1
AND t2.c3 = t4.c3) V
WHERE t5.c1 = V.c1之前加入分解,数据库必须加入t1,t2以及t3用加入他们之前t5。示例5-14从视图V分解t1
如果联接分解t1从视图中进行分解V,如以下查询所示,则数据库可以t1使用t5。联接:
SELECT *
FROM t5, ( SELECT t1.c1, VW_JF_1.item_2
FROM t1, (SELECT t2.c1 item_1, t2.c2 item_2
FROM t2, t3
WHERE t2.c2 = t3.c2
AND t2.c2 = 2
UNION ALL
SELECT t2.c1 item_1, t2.c2 item_2
FROM t2, t4
WHERE t2.c3 = t4.c3) VW_JF_1
WHERE t1.c1 = VW_JF_1.item_1
AND t1.c1 > 1 )
WHERE t5.c1 = V.c1
前面的查询转换将打开新的联接顺序。但是,联接分解规定了特定的联接顺序。例如,在前面的查询中,表t2和t3显示UNION ALL在view 的查询的第一分支中VW_JF_1。数据库必须先t2与联接,t3然后才能与t1联接,该VW_JF_1视图未在视图中定义。施加的加入顺序可能不一定是最佳加入顺序。因此,优化器使用基于成本的转换框架执行联接分解。优化器计算带或不带联接分解的计划成本,然后选择最便宜的计划。
示例5-15删除了视图定义的视图V中t1的因式分解
以下查询与示例5-14中的查询相同,但是删除了视图定义,因此更易于查看因式分解:
SELECT *
FROM t5, (SELECT t1.c1, VW_JF_1.item_2
FROM t1, VW_JF_1
WHERE t1.c1 = VW_JF_1.item_1
AND t1.c1 > 1)
WHERE t5.c1 = V.c1
5.11.4外部联接的因式分解:方案
该数据库支持外部联接,反联接和半联接的联接分解,但仅适用于此类联接中的右边表(从表)。
例如,加入分解可以将以下UNION ALL由上分解查询t2:
SELECT t1.c2, t2.c2
FROM t1, t2
WHERE t1.c1 = t2.c1(+)
AND t1.c1 = 1
UNION ALL
SELECT t1.c2, t2.c2
FROM t1, t2
WHERE t1.c1 = t2.c1(+)
AND t1.c1 = 2
以下示例显示了转换。t2现在,表不再出现在UNION ALL子查询的分支中。
SELECT VW_JF_1.item_2, t2.c2
FROM t2, (SELECT t1.c1 item_1, t1.c2 item_2
FROM t1
WHERE t1.c1 = 1
UNION ALL
SELECT t1.c1 item_1, t1.c2 item_2
FROM t1
WHERE t1.c1 = 2) VW_JF_1
WHERE VW_JF_1.item_1 = t2.c1(+)



