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

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

程序员文章站 2022-07-12 19:29:56
...
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】