設為首頁收藏本站

艾歐踢論壇

 找回密碼
 立即註冊

QQ登錄

只需一步,快速開始

搜索
熱搜: 活動 交友 discuz
查看: 1393|回復: 0
打印 上一主題 下一主題

Oracle union vs union all 用法區別

[複製鏈接]
跳轉到指定樓層
樓主
發表於 2015-1-13 16:36:49 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一.基礎知識:
1.  Union 排序,Union All 不排序。
Union中兩個select 語句查詢欄位類型要匹配,而且欄位個數要相同。
Union在進行表連接以後會對結果進行篩選,刪除重複記錄,對結果進行排序,將排序後的結果返回。   具有distinct 的功能。
Union All 卻僅僅是將兩個select 語句查詢結果合併後返回。可能出現重複記錄。
所以union all 效率要比union高。在能夠確定沒有重複記錄的情況下儘量使用union all。
如果表有多個索引列的時候,用union 替換 where 中的or 效率會提高不少。索引列使用or會造成全資料表掃描。如果有column 沒有使用索引,就得記得or了。
2.  索引:
避免將索引建立在任何可能為空的列上邊。Oracle將無法使用該索引。
避免在索引列上使用 is null  、  is not null。
當索引建立在多個列的時候,只用當索引的第一列被where子句引用時,優化器才會使用該索引,僅使用第二列的時候,優化器就會進行全資料表掃描而忽略該索引。
3.  排序:
Union對兩個結果集進行並集操作,不包括重複行,同時進行預設規則排序;
UnionAll 對兩個結果集進行並集操作,包括重複行,不進行排序;
Intersect對兩個結果集進行交集操作,不包括重複行,同時進行預設規則排序;
Minus對兩個結果集進行差操作,不包括重複行,同時進行預設規則排序。
可以在最後一個結果集中制定Order By 子句改變排序方式。
4.  Oracle 中的in 和 exists
Select* from t1 where x in (select y from t2)
事實上可以理解為:
Select* from t1, (select distinct y from t2) t2 where t1.x = t2.y
從這句很自然的可以想到t2絕對不能是個大表,因為需要對t2進行全表的“唯一排序”,如果t2很大這麼排序的性能是不可忍受的。但是t1可以很大,為什麼呢?最通俗的理解就是因為t1.x = t2.y可以走索引。但這並不是一個很好的解釋。試想如果t1.x 和 t2.y都有索引,我們知道索引是種有序的結構,因此t1和t2之間最佳的方案是走merge join。另外,如果t2.y上有索引,對t2的排序性能也是很大提高。
Select* from t1 where exists ( select null from t2 where y = x )
可以理解為:
Forx in (select * from t1)
Loop
If (exists(select null from t2 where y = x.x)) then
OUTPUTTHE RECODE!
Endif
    End loop
這個更容易理解,t1永遠是個資料表掃描,因此t1絕對不能是個大表,而t2可以很大,因為y=x.x
可以走t2.y的索引。IN適合於外表大而內表小,exists合適外表小而內表大的情況。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 轉播轉播 分享分享 分享淘帖
回復

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

小黑屋|Archiver|手機版|艾歐踢創新工坊    

GMT+8, 2024-5-29 13:51 , Processed in 0.257374 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表