「看這篇就夠了」Mysql join條件是要寫在on裡還是在where裡?

2020-12-25 一線碼農

對於join系列語句,大部分開發人員都經常用到。但是對於裡面的運行原理,我相信很少人真正認識,下面我們從幾個方面介紹下。

為了能夠覆蓋更多的點,這裡複製一位大佬的表和圖。我們先建兩個表和添加一批數據,注意只有a表的f1有索引,a表和B表的數據不完全一致

結果集區別

上圖可以看出,結果集是不一樣的,條件寫在ON裡,數據有6條,比條件放在where裡面多出2條。

算法區別

select * from a left join b on(a.f1=b.f1) and (a.f2=b.f2)語句執行順序是:1、先掃描a表的數據,放到join_buffer中,join_buffer的數據結構是數組。2、順序掃描b表,每一條數據跟join_buffer的a的數據進行on條件判斷,匹配則放入結果集中。最後a中未匹配的補上null,合併到結果集中返回。

以上這種查找方法就是Mysql的Block Nexted Loop Join(簡稱BNL)算法。b表是沒有索引情況下,順序掃描全表根據驅動表join buffer匹配,進而計算結果集!

select * from a left join b on(a.f1=b.f1) where (a.f2=b.f2)語句執行是:因為where條件中b.f2為null值,且mysql優化器會認為這sql具有優化空間。所以就將這個left join的語句優化為join:select * from a left join b where a.f1=b.f1 and a.f2=b.f2。也就是即使我們用了left join 在這裡也不能保證執行順序,因為優化器會進行優化。現在因為a表f1有索引,優化器優化後變成了b表是驅動表,a表是被驅動表,走的是IndexNested-Loop Join(簡稱NLJ)算法。

結論

1、如果要結果集包含左表全部數據,則條件寫在ON裡

2、如果要保證sql性能,可以寫在where裡面

關注我,下一篇繼續介紹這個join話題。

「看這篇就夠了」Mysql大表中查詢全表掃描是否會佔用完內存?

「看這篇就夠了」Mysql事務提交是怎麼在保證性能情況下持久化?

「看這篇就夠了」Mysql幻讀的原理介紹

「看這篇就夠了」Mysql的limit有哪些優點,快來了解下吧

相關焦點

  • MySQL:Left Join 避坑指南
    在我們使用mysql查詢的過程中可謂非常常見,比如博客裡一篇文章有多少條評論、商城裡一個貨物有多少評論、一條評論有多少個贊等等。但是由於對join、on、where等關鍵字的不熟悉,有時候會導致查詢結果與預期不符,所以今天我就來總結一下,一起避坑。這裡我先給出一個場景,並拋出兩個問題,如果你都能答對那這篇文章就不用看了。
  • MySQL:LEFT JOIN 避坑指南
    在我們使用mysql查詢的過程中可謂非常常見,比如博客裡一篇文章有多少條評論、商城裡一個貨物有多少評論、一條評論有多少個贊等等。但是由於對join、on、where等關鍵字的不熟悉,有時候會導致查詢結果與預期不符,所以今天我就來總結一下,一起避坑。這裡我先給出一個場景,並拋出兩個問題,如果你都能答對那這篇文章就不用看了。
  • MySQL:left join 避坑指南
    現象left join在我們使用mysql查詢的過程中可謂非常常見,比如博客裡一篇文章有多少條評論、商城裡一個貨物有多少評論、一條評論有多少個贊等等。但是由於對join、on、where等關鍵字的不熟悉,有時候會導致查詢結果與預期不符,所以今天我就來總結一下,一起避坑。
  • MySql 之 left join 避坑指南
    在我們使用mysql查詢的過程中可謂非常常見,比如博客裡一篇文章有多少條評論、商城裡一個貨物有多少評論、一條評論有多少個贊等等。但是由於對join、on、where等關鍵字的不熟悉,有時候會導致查詢結果與預期不符,所以今天我就來總結一下,一起避坑。這裡我先給出一個場景,並拋出兩個問題,如果你都能答對那這篇文章就不用看了。
  • MySQL中left join的幾個SQL對比
    ,知道邏輯,有預期的結果,好像沒什麼特別要注意的,今天在寫一條SQL邏輯的時候,覺得對於left join的部分還是存在一些誤解。name |+----+-+| 2 | bb || 3 | cc || 4 | bb || 6 | dd |+----+-+4 rows in set (0.00 sec)我們寫一個條基本的left join的SQL,這個時候我們使用name='bb'來作為過濾條件,id作為關聯條件。
  • 我想說:mysql 的 join 真的很弱
    join,這是為什麼?對比1.1 和5.1 步驟sql查詢,4表連接,對我本機mysql來說 ,1.5千萬數據查詢很流利,是一個mysql數據量流利分水嶺。(這個只是現象,不太準確,需要同時計算表的容量)。步驟5.1對比6.1,6.2,6.3,多表join對mysql來說,處理有些吃力。 超過三張表禁止join,這個規則是針對mysql來說的。
  • Mysql - JOIN詳解
    如果之前對不同JOIN的執行結果沒有概念,可以結合這篇文章往下看2 JOIN的執行順序以下是JOIN查詢的通用結構SELECT <row_list> FROM <left_table> <inner|left|right> JOIN <right_table> ON
  • 場景分析:記錄一下使用MySQL的left join時,遇到的坑!
    在我們使用mysql查詢的過程中可謂非常常見,比如博客裡一篇文章有多少條評論、商城裡一個貨物有多少評論、一條評論有多少個贊等等。但是由於對join、on、where等關鍵字的不熟悉,有時候會導致查詢結果與預期不符,所以今天我就來總結一下,一起避坑。這裡我先給出一個場景,並拋出兩個問題,如果你都能答對那這篇文章就不用看了。
  • Mysql left join 轉 inner join
    對於left join,如果where條件裡有被關聯表過濾,left join有可能被轉成inner join ,本案例中shopInfo有ShopCategory = 'LOC'過濾條件;保證shopInfo的記錄非NULL
  • 面試官:left join 後用 on 和 where 有什麼區別?
    不管 and 後面的是 A.id=1 還是 B.id=1, 都顯示出 A 表中所有的記錄,並關聯顯示 B 中對應 A 表中 id 為 1 的記錄或者 B 表中 id 為 1 的記錄。運行 sql :select * from student s left join class c on s.classId=c.id order by s.id運行 sql :
  • 玩轉Mysql系列 - 第25篇:sql中where條件在資料庫中提取與應用淺析
    這是Mysql系列第25篇。讀本篇文章之前,需要先了解一些知識:什麼是索引?mysql索引原理詳解mysql索引管理詳解如何正確的使用索引?上面3篇文章沒有讀過的最好去讀一下,不然後面的內容會難以理解。
  • 關於Left join,避坑指南
    一、left join 之後的記錄有幾條關於這一點,是要理解left join執行的條件。在A join B的時候,我們在on語句裡指定兩表關聯的鍵。只要是符合鍵值相等的,都會出現在結果中。這裡面有一對一,一對多,多對多等幾種情況。我們用例子來說明。1.一對一這種情況最好理解。
  • 關於Left join,你可能不知道這些......
    一、left join 之後的記錄有幾條關於這一點,是要理解left join執行的條件。在A join B的時候,我們在on語句裡指定兩表關聯的鍵。只要是符合鍵值相等的,都會出現在結果中。這裡面有一對一,一對多,多對多等幾種情況。我們用例子來說明。1、一對一這種情況最好理解。
  • MySql之基礎語法篇
    MySql之基礎語法篇 對於mysql來說,存儲引擎,sql優化,慢sql分析,存儲過程,數據結構,事務,並發,鎖等等,感覺每一部分都可以延伸出來一本書的知識,對於剛剛步入工作的我來說想要深入研究還太過遙遠,只能以後討論了,不過對於我這個剛剛從事計算機行業的人來說,一些基本功還是具備的,敲了這麼長時間的代碼,就在這裡做個簡單的記錄吧!
  • 詳細匯總 SQL 語句 Join 連接方式與用法.
    指定連接條件這樣自動找相同列的操作十分方便,同時也十分危險。要是程式設計師粗心地看漏了一些列名,或是對表結構有不正確的預期,可能導致資料庫採用的相等條件比程式設計師設想的要多。SQL也提供了手動指定連接屬性的方法。如要連接表示選課情況的表takes和課程列表course,指定以屬性course_id相等為篩選條件。
  • SQL 語句中 left join 後用 on 還是 where,區別大了!
    不管and 後面的是A.id=1還是B.id=1,都顯示出A表中所有的記錄,並關聯顯示B中對應A表中id為1的記錄或者B表中id為1的記錄。運行sql :select * from student s left join class c on s.classId=c.id order by s.id
  • MySQL Nested-Loop Join 算法
    >然後看看這條 SQL 的 explain 結果:圖 2 不使用索引欄位 join 的 explain 結果與 NLJ 不同的是,由於欄位 b 沒有建索引,所以 t1 每次去 t2 匹配的時候,都要做一次全表掃描,因此整個過程需要掃描的行數是 1000 * 100 = 10萬行,這個算法就是
  • MySQL join 學習
    ON 與 WHERE 在使用 inner join 時,無論是在結果上還是在性能上都沒有區別。從結果上看,inner join 中無論條件寫在 ON 還是 WHERE 後,結果相同。在使用 left/left join 時,結果有區別。
  • 我想說:mysql的join 真的很弱
    來源:ITPUB博客 作者:e71hao 一、 問題提出: 《阿里巴巴JAVA開發手冊》裡面寫超過三張表禁止join,這是為什麼?
  • 「看這篇就夠了」Nginx報錯no resolver defined to resolve解決
    $args;nginx版本這裡就不寫了,遇到類似的問題可以用這兩種方法試下!「看這篇就夠了」Mysql中varchar(20)到底可以存儲多少字符?「看這篇就夠了」Mysql建索引時,status欄位要不要加索引?