Oracle SQL 查詢優化.Part3

一、union

1. union 的處理過程:

union all 是簡單的將結果集合並後返回,想必大家都清楚,這裏就不舉例了。而 union 處理結果集時稍微複雜些,不僅去重,還會排序。union 的處理過程是先取出兩個結果集,再用排序空間刪除重複記錄(所以,不僅僅是去除 union 連接起來的結果集之間的重複數據,而是在整個返回的結果集中去重)。

-- 沒用 union 產生重複記錄
select emp.deptno from emp;

-- 和一個空集進行 union 連接,去重
select emp.deptno from emp
union
select emp.empno from emp where 1 = 2

上邊第二個 sql 中 union 連接了一個有重複記錄的結果集和一個空集,最終返回的結果集只有一條記錄。所以,union 是在整個結果集中去重。

二、with 語句

1. with語法

with 語句的效果很想臨時創建若干個視圖(view),在 sql 執行完畢後銷燬。with 可以創建多個這樣“臨時view”,而且創建次序以上之下,後邊的可以引用前邊已經創建好的“臨時view”。

-- with 語法
with 
e1 as(select emp.* from emp where emp.empsalary >= 3000),
e2 as(select emp.* from emp where emp.deptno = 'dept02'),
e3 as(select e1.empno, e1.deptno, e1.empsalary from e1, e2 where e1.empno = e2.empno)
select * from e3;

e1 查詢工資大於等於 3000 的員工,e2 查詢部門在 dept02 的員工,e3 用empno 關聯 e1、e2 產生的結果集表示“工資大於等於 3000,在 dept02 部門的所有員工”。在這裏,e3 引用了e1 和 e2 兩個“臨時view”。

三、in 和 exists

1. in 與 exists 的區別:

在子查詢中,in 是 把外表和內表做 hash 鏈接,exists 是把內表和外表做 loop 循環。一直以來都說“exists 比 in 效率高”貌似是不準確的。子查詢(內)表大用 exists,子查詢表小用 in。

例如:

表A(小表),表B(大表)

select * from A where id in(select id from B)  -->效率低,用到了A表上cc列的索引
select * from A where exists(select id from B where A.id = B.id)
表A(大表),表B(小表)
select * from B where id in(select id from A)  -->效率高,用到了B表上cc列的索引
select * from B where exists(select id from A where A.id = B.id)
exists 和 in 具體效率上的差異還有待驗證。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章