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

2015-01-21 12:18:01 · 作者: · 浏览: 24
block gets
? ? ? ? 111? consistent gets
? ? ? ? ? 0? physical reads
? ? ? ? ? 0? redo size
? ? ? ? 287? bytes sent via SQL*Net to client
? ? ? ? 404? bytes received via SQL*Net from client
? ? ? ? ? 1? SQL*Net roundtrips to/from client
? ? ? ? ? 8? sorts (memory)
? ? ? ? ? 0? sorts (disk)
? ? ? ? ? 0? rows processed



从上述显示内容可以看出,对表sales的全表扫描只在Id=15的执行步骤处出现了一次,这说明同样的SQL在Oracle 11gR2中只需要全表扫描sales一次,另外,Id=2的执行步骤的Operation列的值是“VIEW”,对应的 Name列的值是“VW_JF_SET$0F531EB5”(这里VW_JF_SET$0F531EB5中的关键字是JF是Join Factorization的缩写),同时Id=1的执行步骤的Operation列的值是”HASH JOIN”。种种迹象都说明Oracle已经把范例SQL中union all的公共部分表sales提了出来,然后和union all 剩下的部分所形成的内嵌视图VW_JF_SET$0F531EB5做了一个哈希连接,即Oracle已经对范例SQL做了连接因式分解。


连接因式分解除了能够避免对公共部分中所包含的表做重复访问之外,还可以提供更多的执行路径给优化器做选择,这就增加了走出更高效执行计划的可能性。


创建一个视图view_jf,其视图定义SQL语句就是范例SQL:
SQL> create or replace view view_jf as
? 2? select t2.prod_id as prod_id
? 3? from sales t2,customers t3
? 4? where t2.cust_id=t3.cust_id
? 5? and t3.cust_gender='MALE'
? 6? union all
? 7? select t2.prod_id as prod_id
? 8? from sales t2,customers t3
? 9? where t2.cust_id=t3.cust_id
?10? and t3.cust_gender='FEMALE';


View created.



然后我们来看如下形式的SQL1:
select t1.prod_id,t1.prod_name
?from products t1,view_jf
?where t1.prod_id=view_jf.prod_id
?and t1.prod_list_price>1000;


在范例SQL1中,表products和视图view_jf做了表连接,而view_jf又是表sales和customers做表连接且做union all的视图。因为view_jf中包含了集合运算符union all,所以Oracle不能对它做视图合并,即Oracle必须将view_jf的定义SQL语句当作一个整体来单独执行,这也就意味着sales必须和customers做表连接,然后才能和表products再做表连接。


在Oracle10gr2中执行范例SQL1:
SQL> select t1.prod_id,t1.prod_name
? 2? from products t1,view_jf
? 3? where t1.prod_id=view_jf.prod_id
? 4? and t1.prod_list_price>1000;


no rows selected



Execution Plan
----------------------------------------------------------
Plan hash value: 3095468170


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