mysql中not in和not exists兩種查詢到底哪種快

時間 2021-06-09 05:22:57

1樓:聿明leslie

看了這個問題的不少答案,給我的感覺就是回答得都太過表面。雖然在OceanBase我是從事SQL方向研發工作的,但總的來說,我實在害怕回答SQL方向的問題,給我的感覺就是每次看到這類問題,都太難回答了。

混跡知乎的資料庫板塊好幾年,看了好多問題,總體感覺就是國內研究資料庫的環境太差,大家對資料庫核心的了解還是很少,而且關注點也多在事務和儲存方面,對SQL了解真是少的可憐,所以雖然在OB我主攻的方向是SQL,但回答問題最多的還是事務相關的,因為這部分的問題至少提問者能夠描述清楚,把背景講清楚,而一些關於SQL的問題,基本就是我這條SQL很慢,有沒有大牛能幫我優化一下?沒有schema資訊,沒有表資料的分布情況,讓你看了問題也是摸不著方向。

MySQL大家都吐槽它的優化器弱,但優化器弱不代表沒有優化器,一些簡單的優化別人還是能做的,對於not in和not exists在一些簡單的SQL中可能這兩個都會優化成同一種執行路徑,所以你問它們誰的執行效率更高,怎麼回答?建議大家有這樣的問題的時候先去看看MySQL文件吧,MySQL的使用者手冊雖然是英文的,但通俗易懂,看起來也不會吃力,看看MySQL subquery的四種優化策略,這個問題自然就明白了。

2樓:ati att

Atitit notin 效能優化演算法總結

1.1. in和exists區別 1

1.2. notin 能不能走索引??答案是有些可以有些不可以 1

1.3. 雖然Notin裡面排除多的情況下可以走索引,但資料庫具體實現可能沒有實現,此時可以使用join代替 2

1.4. 和 Not Exists的關係 2

in和exists執行時,in是先執行子查詢中的查詢,然後再執行主查詢。而exists查詢它是先執行主查詢,即外層表的查詢,然後再執行子查詢。

exists 和 in 在執行時效率單從執行時間來說差不多,exists要稍微優於in。在使用時一般應該是用exists而不用in

如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in,反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。IN時不對NULL進行處理。

不過這個不知是sql標準這樣規定,還是只是某乙個資料庫具體實現這樣的演算法規範。。

少量排除情況下 ,notin 基本就是等同遍歷了。Notin裡面資料量少的情況下,走不走索引差別不大

Notin裡面排除數量較多的情況下,走索引還是有很大差別的。

比如表裡面十萬資料,排除一條,走不走索引效果是一樣的。。但如果排除上萬資料,那走走索引還是有用的,排除的資料越多,走索引效果越好。

具體的實現實現效果和資料庫型別和版本相關。一般越高階資料庫與版本會對此優化越好。。

如果遇到相關資料庫對此語句優化不好,那就需要利用適當調整sql語句,換個等義的更高效能寫法(一般可讀性會因此下降) 或者利用儲存過程自定義函式等自己實現效能高的notin演算法,或者用程式語言實現

代價就是可讀性相對會下降寫。。優先使用notin,其次join代替可讀性優先保證

含義上說 notin 基本就是notexist 也有可能是sql標準,待確定

有可能不同的資料庫區分是為了實現倆種不同的查詢演算法有些資料庫倆種演算法幾乎一樣效率,有些資料庫實現的不一樣。。

而且資料量大小不同的情況下,可能會走不同的路徑,不能一概而論。。

用IN寫出來的SQL的優點是比較容易寫及清晰易懂,這比較適合現代軟體開發的風格。

但是用IN的SQL效能總是比較低的,從SQL執行的步驟來分析用IN的SQL與不用IN的SQL有以下區別:

SQL試圖將其轉換成多個表的連線,如果轉換不成功則先執行IN裡面的子查詢,再查詢外層的表記錄,如果轉換成功則直接採用多個表的連線方式查詢。由此可見用IN的SQL至少多了乙個轉換的過程。一般的SQL都可以轉換成功

3樓:Ryou ikonn

網路上很多知識都是錯的,需要帶著質疑的態度去學。

網上認為not in 比not exists慢是因為not in 進行了全表掃瞄沒有利用上索引,這是不對的,除非查詢的字段上有 null值導致b 樹沒有構建好,導致索引失效不然的話是同樣只要查索引就行了的。如果資料庫的查詢如此之蠢乙個not in 就不會用到索引了那這種資料庫應該被淘汰了。

4樓:one flower

在查詢的兩個表大小相當的情況下,3種查詢方式的執行時間通常是:

EXISTS <= IN <= JOIN

NOT EXISTS <= NOT IN <= LEFT JOIN只有當表中字段允許NULL時,NOT IN的方式最慢:

NOT EXISTS <= LEFT JOIN <= NOT IN但是如果兩個表中乙個較小,乙個較大,則子查詢表大的用exists,子查詢錶小的用in,因為in 是把外表和內錶作hash 連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。

參考自:EXISTS、IN與JOIN的用法區別

5樓:王佐之才荀彧

當然是這樣的,因為in會使用你的子查詢欄位去到主表匹配你需要的行,而exists是根據匹配項去判斷是或者否,然後根據是否決定結果,子查詢的表大,用exists判斷,效率就會高,而當子查詢很小的時候,直接匹配你需要的值則更快。比如主表4萬行,子查詢裡面有5條資料,那麼exists會把4萬行在子查詢裡面進行匹配,匹配上了就顯示,匹配不上就不顯示,所以需要判斷4萬次,而in則會在主表4萬行裡面去檢索這5條記錄,由於索引等等的存在,in的效率通常會更高,但是如果反過來,主表5條記錄,子查詢裡面有4萬行,exists只進行5次判斷,而in會用4萬個資料去匹配這5條記錄,當然exists更快。

Mysql中怎樣實現check約束?

愛可生雲資料庫 現在要說的是在列這一層次過濾的基於表定義之前就規範好的 CHECK 約束。MySQL 版本 8.0.16 mysql create table f1 r1 int constraint tb f1 r1 chk1 check mod r1,3 0 Query OK,0 rows af...

MySQL中單引號和反引號的區別是什麼?

八五影食 單引號和反引號使用場景 反引號是為了區分MySQL的保留字與普通字元而引入的符號。例 create database create 如果不用反引號,MySQL將把create視為保留字而導致出錯,所以,有MySQL保留字作為欄位的,必須加上反引號來區分。引號一般用在字段的值,如果字段值是字...

MySQL中NULL值有什麼意義?

Jack 自己回答自己的問題吧。先吐槽下知乎,居然沒有顯示問題提問時間的地方。這個問題大概是自己剛剛入行做DBA 的時候,一直沒搞懂NULL到底是幹嘛的,後來經過陸續的學習了解,有了一些認知 NULL值的含義 1.NULL不是空 2.什麼是空,空就是沒有,比如說,錢包裡是空的,這個位置沒人佔,但是,...