
exists和in的效率區別(數據庫中IN和EXISTS有什么區別)

大家好,今天來為大家分享exists和in的效率區別的一些知識點,和數據庫中IN和EXISTS有什么區別的問題解析,大家要是都明白,那么可以忽略,如果不太清楚的話可以看...
大家好,今天來為大家分享exists和in的效率區別的一些知識點,和數據庫中IN和EXISTS有什么區別的問題解析,大家要是都明白,那么可以忽略,如果不太清楚的話可以看看本篇文章,相信很大概率可以解決您的問題,接下來我們就一起來看看吧!
如何在mysql中查詢當前數據上一條和下一條的記錄
我來講一下這個問題吧:
題主說的查詢應該是這樣吧:select*fromawhereidin(selectidfromb);對于這條sql語句它的執行計劃其實并不是先查詢出b表的所有id,然后再與a表的id進行比較。mysql會把in子查詢轉換成exists相關子查詢,所以它實際等同于這條sql語句:select*fromawhereexists(select*frombwhereb.id=a.id);
而exists相關子查詢的執行原理是:循環取出a表的每一條記錄與b表進行比較,比較的條件是a.id=b.id.看a表的每條記錄的id是否在b表存在,如果存在就行返回a表的這條記錄。
exists查詢有什么弊端?由exists執行原理可知,a表(外表)使用不了索引,必須全表掃描,因為是拿a表的數據到b表查。而且必須得使用a表的數據到b表中查(外表到里表中),順序是固定死的。
如何優化?建索引。但是由上面分析可知,要建索引只能在b表的id字段建,不能在a表的id上,mysql利用不上。
這樣優化夠了嗎?還差一些。由于exists查詢它的執行計劃只能拿著a表的數據到b表查(外表到里表中),雖然可以在b表的id字段建索引來提高查詢效率。但是并不能反過來拿著b表的數據到a表查,exists子查詢的查詢順序是固定死的。
為什么要反過來?因為首先可以肯定的是反過來的結果也是一樣的。這樣就又引出了一個更細致的疑問:在雙方兩個表的id字段上都建有索引時,到底是a表查b表的效率高,還是b表查a表的效率高?
該如何進一步優化?把查詢修改成innerjoin連接查詢:select*fromainnerjoinbona.id=b.id;(但是僅此還不夠,接著往下看)
為什么不用leftjoin和rightjoin?這時候表之間的連接的順序就被固定住了,
比如左連接就是必須先查左表全表掃描,然后一條一條的到另外表去查詢,右連接同理。仍然不是最好的選擇。
為什么使用innerjoin就可以?innerjoin中的兩張表,如:ainnerjoinb,但實際執行的順序是跟寫法的順序沒有半毛錢關系的,最終執行也可能會是b連接a,順序不是固定死的。如果on條件字段有索引的情況下,同樣可以使用上索引。
那我們又怎么能知道a和b什么樣的執行順序效率更高?答:你不知道,我也不知道。誰知道?mysql自己知道。讓mysql自己去判斷(查詢優化器)。具體表的連接順序和使用索引情況,mysql查詢優化器會對每種情況做出成本評估,最終選擇最優的那個做為執行計劃。
在innerjoin的連接中,mysql會自己評估使用a表查b表的效率高還是b表查a表高,如果兩個表都建有索引的情況下,mysql同樣會評估使用a表條件字段上的索引效率高還是b表的。
而我們要做的就是:把兩個表的連接條件的兩個字段都各自建立上索引,然后explain一下,查看執行計劃,看mysql到底利用了哪個索引,最后再把沒有使用索引的表的字段索引給去掉就行了。
數據庫中IN和EXISTS有什么區別
沒有什么區別,兩者都是包含的意思,但是esists的效率比in要高。建議別用in,影響效率,如果只有兩三個條件,就用or代替,如果值比較多,就用exists.例如select*fromtablewhere(name='1'orname='2')別寫成namein('1','2')如果數據量比較大select*fromtablewherenameexists(selectnamefromtable2);
好了,本文到此結束,如果可以幫助到大家,還望關注本站哦!
本文鏈接:http://www.wzyaohuidianqi.cn/ke/3096.html
