Oracle 连接因式分解(Join Factorization)(一)

2015-01-21 12:18:01 · 作者: · 浏览: 27

我们来看一个连接因式分解的实例。先来看用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):
---------------------------------------------------


? 2 - access("T2"."CUST_ID"="T3"."CUST_ID")
? 3 - filter("T3"."CUST_GENDER"='MALE')
? 4 - access(ROWID=ROWID)
? 6 - access("T3"."CUST_GENDER"='MALE')
? 10 - access("T2"."CUST_ID"="T3"."CUST_ID")
? 11 - filter("T3"."CUST_GENDER"='FEMALE')
? 12 - access(ROWID=ROWID)
? 14 - access("T3"."CUST_GENDER"='FEMALE')



Statistics
---