oracle中的exists 和not exists 用法 in與exists語句的效率問題

來源:互聯網
上載者:User

標籤:

博文來源(oracle中的exists 和not exists 用法):http://chenshuai365-163-com.iteye.com/blog/1003247

博文來源(  in與exists語句的效率問題):http://www.cnblogs.com/iceword/archive/2011/02/15/1955337.html

(一)

exists (sql 返回結果集為真)
not exists (sql 不返回結果集為真)
如下:
表A
ID NAME

1    A1
2    A2
3  A3

表B
ID AID NAME
1    1 B1
2    2 B2
3    2 B3

表A和表B是1對多的關係 A.ID => B.AID

 1 SELECT ID,NAME FROM A WHERE EXIST (SELECT * FROM B WHERE A.ID=B.AID) 2 執行結果為 3 1 A1 4 2 A2 5 原因可以按照如下分析 6 SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1) 7 --->SELECT * FROM B WHERE B.AID=1有值返回真所以有資料 8  9 SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)10 --->SELECT * FROM B WHERE B.AID=2有值返回真所以有資料11 12 SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)13 --->SELECT * FROM B WHERE B.AID=3無值返回真所以沒有資料14 15 NOT EXISTS 就是反過來16 SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID)17 執行結果為18 3 A3 

 


(二)SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差別:

 

  IN 關鍵字使您得以選擇與列表中的任意一個值匹配的行。確定給定的值是否與子查詢或列表中的值相匹配。  (1)獲得居住在 California、Indiana 或 Maryland 州的所有作者的姓名和州的列表時,就需要下列查詢:  SELECT ProductID, ProductName FROM Northwind.dbo.Products WHERE CategoryID = 1 OR CategoryID = 4 OR CategoryID = 5  然而,如果使用 IN,少鍵入一些字元也可以得到同樣的結果:  SELECT ProductID, ProductName FROM Northwind.dbo.Products WHERE CategoryID IN (1, 4, 5)  IN 關鍵字之後的項目必須用逗號隔開,並且括在括弧中。  (2)下列查詢在 titleauthor 表中尋找在任一種書中得到的版稅少於 50% 的所有作者的 au_id,然後從 authors 表中選擇 au_id 與titleauthor 查詢結果匹配的所有作者的姓名:  SELECT au_lname, au_fname FROM authors WHERE au_id IN (SELECT au_id FROM titleauthor WHERE royaltyper <50)  結果顯示有一些作者屬於少於 50% 的一類。  NOT IN:通過 NOT IN 關鍵字引入的子查詢也返回一列零值或更多值。  以下查詢尋找沒有出版過商業書籍的出版商的名稱。  SELECT pub_name FROM publishers WHERE pub_id NOT IN (SELECT pub_id FROM titles WHERE type = ‘business‘)  使用 EXISTS 和 NOT EXISTS 引入的子查詢可用於兩種集合原理的操作:交集與差集。     (1) 兩個集合的交集包含同時屬於兩個原集合的所有元素。    (2)差集包含只屬於兩個集合中的第一個集合的元素。    EXISTS:指定一個子查詢,檢測行的存在。  本樣本所示查詢尋找由位於以字母 B 開頭的城市中的任一出版商出版的書名:  SELECT DISTINCT pub_name FROM publishers WHERE EXISTS (SELECT * FROM titles WHERE pub_id = publishers.pub_id AND type =‘business‘)  SELECT distinct pub_name FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE type = ‘business‘)
  兩者的區別:  EXISTS:後面可以是整句的查詢語句如:SELECT * FROM titles  IN:後面只能是對單列:SELECT pub_id FROM titles  NOT EXISTS:  例如,要尋找不出版商業書籍的出版商的名稱:  SELECT pub_name FROM publishers WHERE NOT EXISTS (SELECT * FROM titles WHERE pub_id = publishers.pub_id AND type =  ‘business‘)  下面的查詢尋找已經不銷售的書的名稱:  SELECT title FROM titles WHERE NOT EXISTS (SELECT title_id FROM sales WHERE title_id = titles.title_id)

 

(三)In 於 EXISTS 的效率問題

select * from Awhere id in(select id from B)以上查詢使用了in語句,in()只執行一次,它查出B表中的所有id欄位並緩衝起來.之後,檢查A表的id是否與B表中的id相等,如果相等則將A表的記錄加入結果集中,直到遍曆完A表的所有記錄.它的查詢過程類似於以下過程List resultSet=[];Array A=(select * from A);Array B=(select id from B);for(int i=0;i<A.length;i++) {   for(int j=0;j<B.length;j++) {      if(A[i].id==B[j].id) {         resultSet.add(A[i]);         break;      }   }}return resultSet;可以看出,當B表資料較大時不適合使用in(),因為它會B表資料全部遍曆一次.如:A表有10000條記錄,B表有1000000條記錄,那麼最多有可能遍曆10000*1000000次,效率很差.再如:A表有10000條記錄,B表有100條記錄,那麼最多有可能遍曆10000*100次,遍曆次數大大減少,效率大大提升.結論:in()適合B表比A表資料小的情況select a.* from A awhere exists(select 1 from B b where a.id=b.id)以上查詢使用了exists語句,exists()會執行A.length次,它並不緩衝exists()結果集,因為exists()結果集的內容並不重要,重要的是結果集中是否有記錄,如果有則返回true,沒有則返回false.它的查詢過程類似於以下過程List resultSet=[];Array A=(select * from A)for(int i=0;i<A.length;i++) {   if(exists(A[i].id) {    //執行select 1 from B b where b.id=a.id是否有記錄返回       resultSet.add(A[i]);   }}return resultSet;當B表比A表資料大時適合使用exists(),因為它沒有那麼遍曆操作,只需要再執行一次查詢就行.如:A表有10000條記錄,B表有1000000條記錄,那麼exists()會執行10000次去判斷A表中的id是否與B表中的id相等.如:A表有10000條記錄,B表有100000000條記錄,那麼exists()還是執行10000次,因為它只執行A.length次,可見B表資料越多,越適合exists()發揮效果.再如:A表有10000條記錄,B表有100條記錄,那麼exists()還是執行10000次,還不如使用in()遍曆10000*100次,因為in()是在記憶體裡遍曆比較,而exists()需要查詢資料庫,我們都知道查詢資料庫所消耗的效能更高,而記憶體比較很快.結論:exists()適合B表比A表資料大的情況當A表資料與B表資料一樣大時,in與exists效率差不多,可任選一個使用.

 



 

oracle中的exists 和not exists 用法 in與exists語句的效率問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.