Oracle 连接因式分解(Join Factorization)

连接因式分解(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):
---------------------------------------------------

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1f55a25d95345ec37ee774c4c070c459.html