SQL語句主要的連接方法
a) Nested-loop join
適合于小表(幾千條,幾萬條記錄)與大表做聯接
在聯接列上有索引。
分內表和外表(驅動表),靠近from子句的是內表。從效率上講,小表應該作外表,大表應該作內表,即大表查詢時走索引。
COST= Access cost of A(驅動表) + (access cost of B * number of rows from A)
成本計算方法:
設小表100行,大表100000行。
兩表均有索引:
如果小表在內,大表在外(驅動表)的話,則掃描次數為:
100000+100000*2 (其中2表示IO次數,一次索引,一次數據)
如果大表在內,小表在外(驅動表)的話,則掃描次數為:
100+100*2.
兩表均無索引:
如果小表在內,大表在外的話,則掃描次數為:
100000+100*100000
如果大表在內,小表在外的話,則掃描次數為:
100+100000*100
注意:如果一個表有索引,一個表沒有索引,ORACLE會將沒有索引的表作驅動表。如果兩個表都有索引,則外表作驅動表。如果兩個都沒索引的話,則也是外表作驅動表。
基本的執行計劃如下所示:
NESTED LOOPS
TABLE ACCESS (BY ROWID) OF our_outer_table
INDEX (..SCAN) OF outer_table_index(….)
TABLE ACCESS (BY ROWID) OF our_inner_table
INDEX (..SCAN) OF inner_table_index(….)
b) Hash join
適合于大表與大表,小表(幾十萬,幾百萬)與大表之間的聯連。
聯接列上不需要索引。
基本執行計劃如下:
HASH JOIN
TABLE ACCESS (….) OF tableA
TABLE ACCESS (….) OF tableB
cost= (access cost of A * number of hash partitions of B) + access cost of B
可以看出主要成本在于A表是否可以被Cache。Hash_area_size的大小將決定Hash Join的主要成本。可以看出Hash Join的成本和返回集合并沒有直接的關系,所以當返回結果集比較大的時候一般具有較好的性能。
為了加快hash join的速度,可以調大hash_area_size和pga_aggregate_target(默認為25M)的值。
c) Sort Merge join
每一個Row Source在Join列上均排序。
然后兩個排序后的Row Source合并后,作一個結果集返回。
Sort/Merge Join僅僅對equal Join有效。
基本執行計劃
MERGE (JOIN)
SORT (JOIN)
TABLE ACCESS (….) OF tableA
SORT (JOIN)
TABLE ACCESS (….) OF tableB
cost= access cost of A + access cost of B +(sort cost of A + sort cost of B)
可以看出Sort的成本是Merge Join的主要構成部分。這樣sort_area_size的大小將很大程度決定Merge Join的大小。同樣如果A表或者B表已經經過排序的,那么Merge Join往往具有很好的性能。其不會走索引。
沒有驅動表的概念,即時響應能力較差。
a) Nested-loop join
適合于小表(幾千條,幾萬條記錄)與大表做聯接
在聯接列上有索引。
分內表和外表(驅動表),靠近from子句的是內表。從效率上講,小表應該作外表,大表應該作內表,即大表查詢時走索引。
COST= Access cost of A(驅動表) + (access cost of B * number of rows from A)
成本計算方法:
設小表100行,大表100000行。
兩表均有索引:
如果小表在內,大表在外(驅動表)的話,則掃描次數為:
100000+100000*2 (其中2表示IO次數,一次索引,一次數據)
如果大表在內,小表在外(驅動表)的話,則掃描次數為:
100+100*2.
兩表均無索引:
如果小表在內,大表在外的話,則掃描次數為:
100000+100*100000
如果大表在內,小表在外的話,則掃描次數為:
100+100000*100
注意:如果一個表有索引,一個表沒有索引,ORACLE會將沒有索引的表作驅動表。如果兩個表都有索引,則外表作驅動表。如果兩個都沒索引的話,則也是外表作驅動表。
基本的執行計劃如下所示:
NESTED LOOPS
TABLE ACCESS (BY ROWID) OF our_outer_table
INDEX (..SCAN) OF outer_table_index(….)
TABLE ACCESS (BY ROWID) OF our_inner_table
INDEX (..SCAN) OF inner_table_index(….)
b) Hash join
適合于大表與大表,小表(幾十萬,幾百萬)與大表之間的聯連。
聯接列上不需要索引。
基本執行計劃如下:
HASH JOIN
TABLE ACCESS (….) OF tableA
TABLE ACCESS (….) OF tableB
cost= (access cost of A * number of hash partitions of B) + access cost of B
可以看出主要成本在于A表是否可以被Cache。Hash_area_size的大小將決定Hash Join的主要成本。可以看出Hash Join的成本和返回集合并沒有直接的關系,所以當返回結果集比較大的時候一般具有較好的性能。
為了加快hash join的速度,可以調大hash_area_size和pga_aggregate_target(默認為25M)的值。
c) Sort Merge join
每一個Row Source在Join列上均排序。
然后兩個排序后的Row Source合并后,作一個結果集返回。
Sort/Merge Join僅僅對equal Join有效。
基本執行計劃
MERGE (JOIN)
SORT (JOIN)
TABLE ACCESS (….) OF tableA
SORT (JOIN)
TABLE ACCESS (….) OF tableB
cost= access cost of A + access cost of B +(sort cost of A + sort cost of B)
可以看出Sort的成本是Merge Join的主要構成部分。這樣sort_area_size的大小將很大程度決定Merge Join的大小。同樣如果A表或者B表已經經過排序的,那么Merge Join往往具有很好的性能。其不會走索引。
沒有驅動表的概念,即時響應能力較差。