关于Oralce中的连接(外连接和内连接)

阅读更多
Note:2009-1-15
Oracle必须为每对行源执行连接操作,连接的方法包括嵌套循环、排序合并、散列连接、笛卡尔积等。
1.嵌套循环连接的成本计算公式:
cost = access cost of A + (access cost of B * number of rows from A)
2.散列连接的成本计算公式:
cost = (access cost of A * number of hash partitions of B) + access cost of B
3.排序合并连接的成本计算公式:
cost = access cost of A + access cost of B + (sort cost of A + sort cost of B)
********************
Note:2009-1-15
1.use_nl:use nesting loop
2.use_hash:use hash
3.use_merge use merge
*****************
Note:2009-1-15
SQL> show parameter workarea_size_policy

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
workarea_size_policy                 string      AUTO

SQL> show parameter pga_aggregate_target

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target                 big integer 629145600
*****************************
Note:2009-1-15
不论是嵌套循环外连接还是散列外连接,CBO不会根据成本去选择连接顺序,被驱动的表总是含有(+)的一方:
SQL> select /*+ordered use_nl(t1 t2)*/ t1.msisdn,t2.msisdn from t1,t2 where t1.msisdn(+)=t2.msisdn;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=100 Card=99 Bytes=2178)
   1    0   NESTED LOOPS (OUTER) (Cost=100 Card=99 Bytes=2178)
   2    1     INDEX (FULL SCAN) OF 'IND_T2' (NON-UNIQUE) (Cost=1 Card=99 Bytes=1089)
   3    1     INDEX (RANGE SCAN) OF 'IND_T1' (NON-UNIQUE) (Cost=1 Card=1 Bytes=11)

虽然使用了ORDERED提示,试图以t1作为驱动表,可是由于是外连接,仍然是以t2作为驱动表。换成散列连接也是一样

SQL> select /*+ordered use_hash(t1 t2)*/ t1.msisdn,t2.msisdn from t1,t2 where t1.msisdn(+)=t2.msisdn;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=99 Bytes=2178)
   1    0   HASH JOIN (OUTER) (Cost=4 Card=99 Bytes=2178)
   2    1     INDEX (FULL SCAN) OF 'IND_T2' (NON-UNIQUE) (Cost=1 Card=99 Bytes=1089)
   3    1     INDEX (FAST FULL SCAN) OF 'IND_T1' (NON-UNIQUE) (Cost=2 Card=999 Bytes=10989)

******************************
Note:2009-1-15
select t1.msisdn,t2.msisdn
from t1
full outer join t2
on t1.msisdn=t2.msisdn
order by t2.msisdn

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=15 Card=1000 Bytes=36000)
   1    0   SORT (ORDER BY) (Cost=15 Card=1000 Bytes=36000)
   2    1     VIEW (Cost=6 Card=1000 Bytes=36000)
   3    2       UNION-ALL
   4    3         NESTED LOOPS (OUTER) (Cost=2 Card=999 Bytes=21978)
   5    4           INDEX (FAST FULL SCAN) OF 'IND_T1' (NON-UNIQUE) (Cost=2 Card=999 Bytes=10989)
   6    4           INDEX (RANGE SCAN) OF 'IND_T2' (NON-UNIQUE)
   7    3         HASH JOIN (ANTI) (Cost=4 Card=1 Bytes=22)
   8    7           INDEX (FULL SCAN) OF 'IND_T2' (NON-UNIQUE) (Cost=1 Card=99 Bytes=1089)
   9    7           INDEX (FAST FULL SCAN) OF 'IND_T1' (NON-UNIQUE) (Cost=2 Card=999 Bytes=10989)
**********************************************************

说明:full outer join = left outer join + right outer join +union all

oracle中hint的用法: select /*+keyword_parameter*/ selected_column_set from table_name where query_condition

Note:2009-1-15
排序合并连接(Sort Merge Join, SMJ):
对于非等值连接,这种连接方式的效率是比较高的,因此主要用于不等价连接,如<、 <=、 >、 >=,但是不包括 <>,如果在关联的列上都有索引,效果更好。对于将两个较大的row source做连接,或者连接列缺乏可使用或可选择性的索引,该连接方法比NL连接要好一些。但是如果sort merge返回的row source过大,则又会导致使用过多的rowid在表中查询数据时,数据库性能下降,因为过多的I/O。所有的表都需要排序。它为最优化的吞吐量而设计,并且在结果没有全部找到前不返回数据。
嵌套循环(Nested Loops, NL):
如果driving row source(外部表)比较小,并且在inner row source(内部表)上 有唯一索引,或有高选择性非唯一索引时,使用这种方法可以得到较好的效率。
NESTED LOOPS有其它连接方法没有的的一个优点是:可以先返回已经 连接的行,而不必等待所有的连接操作理完才返回数据, 这可以实现快速的响应时间。
哈希连接(Hash Join, HJ):
一般来说,其效率应该好于其它2种连接,但是这种连接只能用在 CBO优化器中,而且需要设置合适的hash_area_size参数, 才能取得较好的性能。
在两个较大的row source之间连接时会取得相对较好的效率,在一个 row source较小时则能取得更好的效率。只能用于等值连接中

编写于【2009-01-15】

你可能感兴趣的:(oracle,join,inner,outer)