欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

Oracle 连接因式分解(Join Factorization)

程序员文章站 2024-01-16 09:52:16
...

连接因式分解(Join Factorization)是优化器处理带union all的目标SQL的一种优化手段,它是指优化器在处理以union all连接的目标

连接因式分解(Join Factorization)是优化器处理带union all的目标SQL的一种优化手段,它是指优化器在处理以union all连接的目标SQL的各个分支时,不再原封不动地分别重复执行每个分支,而是会把各个分支中公共的部分提出来作为一个单独的结果集,然后再和原union all中剩下的部分做表连接。连接因式分解在Oracle 11gr2中才被引入,它的好处是显而易见的。如果不把union all中公共的部分提出来,则意味着这些公共部分中所包含的表会在union all的各个分支中被重复访问;而连接因式分解则能够在最大程度上避免这种重复访问现象的产生,当union all的公共部分所包含的表的数据量很大时,减少一次对大表的重复访问,那也意味着执行效率的巨大提升。

我们来看一个连接因式分解的实例。先来看用union all连接的例子:
select t2.prod_id as prod_id
from sales t2,customers t3
where t2.cust_id=t3.cust_id
and t3.cust_gender='MALE'
union all
select t2.prod_id as prod_id
from sales t2,customers t3
where t2.cust_id=t3.cust_id
and t3.cust_gender='FEMALE';


范例SQL的union all的各个分支中仅仅是针对表customers的列cust_gender的限制条件不一样,剩下的部分都是一模一样的,这也意味着表sales就是范例SQL的公共部分。如果这里Oracle不把sales表提出来,不对此SQL做连接因式分解,那就意味着要重复访问表sales两次。

来验证一下。先在Oracle 10gr2中执行范例SQL:
SQL> select t2.prod_id as prod_id
2 from sales t2,customers t3
3 where t2.cust_id=t3.cust_id
4 and t3.cust_gender='MALE'
5 union all
6 select t2.prod_id as prod_id
7 from sales t2,customers t3
8 where t2.cust_id=t3.cust_id
9 and t3.cust_gender='FEMALE';

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 4184572088

------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1837K| 28M| 1098 (54)| 00:00:14 | | |
| 1 | UNION-ALL | | | | | | | |
|* 2 | HASH JOIN | | 918K| 14M| 549 (8)| 00:00:07 | | |
|* 3 | VIEW | index$_join$_002 | 27236 | 186K| 122 (4)| 00:00:02 | | |
|* 4 | HASH JOIN | | | | | | | |
| 5 | BITMAP CONVERSION TO ROWIDS| | 27236 | 186K| 2 (0)| 00:00:01 | | |
|* 6 | BITMAP INDEX SINGLE VALUE | CUSTOMERS_GENDER_BIX | | | | | | |
| 7 | INDEX FAST FULL SCAN | CUSTOMERS_PK | 27236 | 186K| 147 (2)| 00:00:02 | | |
| 8 | PARTITION RANGE ALL | | 918K| 8075K| 413 (6)| 00:00:05 | 1 | 28 |
| 9 | TABLE ACCESS FULL | SALES | 918K| 8075K| 413 (6)| 00:00:05 | 1 | 28 |
|* 10 | HASH JOIN | | 918K| 14M| 549 (8)| 00:00:07 | | |
|* 11 | VIEW | index$_join$_004 | 27750 | 189K| 122 (4)| 00:00:02 | | |
|* 12 | HASH JOIN | | | | | | | |
| 13 | BITMAP CONVERSION TO ROWIDS| | 27750 | 189K| 2 (0)| 00:00:01 | | |
|* 14 | BITMAP INDEX SINGLE VALUE | CUSTOMERS_GENDER_BIX | | | | | | |
| 15 | INDEX FAST FULL SCAN | CUSTOMERS_PK | 27750 | 189K| 147 (2)| 00:00:02 | | |
| 16 | PARTITION RANGE ALL | | 918K| 8075K| 413 (6)| 00:00:05 | 1 | 28 |
| 17 | TABLE ACCESS FULL | SALES | 918K| 8075K| 413 (6)| 00:00:05 | 1 | 28 |
------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------