mysql的left join和inner join的效率對比,以及如何優化
一、前言
最近在寫程式碼的時候,遇到了需要多表連線的一個問題,初始sql類似於:
select * from a left join b on a.x = b.x left join c on c.y = b.y left join d on d.z=c.z
這樣的多個left join
組合,一方面是心裡有點不舒服,總覺得這種寫法是有問題的,一方面有有點好奇,直接用inner join
會怎樣呢?差別在哪裡?後續使用inner join
發現速度要比left join
快一些,所以這邊就研究一下這個問題。
二、left join為什麼會比 inner join 慢
1、關於邏輯運算量
關於left join
的概念,大家是都知道的(返回左邊全部記錄,右表不滿足匹配條件的記錄對應行返回null),那麼單純的對比邏輯運算量的話,inner join
是隻需要返回兩個表的交集部分,left join
多返回了一部分左表沒有返回的資料。
2、關於mysql連線的演算法 Nest Loop Join(巢狀聯接迴圈)
這個演算法是mysql預設的連線演算法,類似於我們php程式的三個巢狀迴圈:
(foreach a as v){
(foreach b as v1){
(foreach c as v2){
}
}
}
從演算法上來看,根據mysql文件,inner join
在連線的時候,mysql會自動選擇較小的表來作為驅動表,從而達到減少迴圈次數的目的。我們在使用left join
表的時候,預設是使用左表作為驅動表,那麼此時左表的大小是我們來控制的,如果控制不當,左表比較大,那麼自然迴圈次數也會變多,效率會下降。
根據這兩方面的對比,left join
明顯被秒成渣,但是我們的實際業務卻經常需要使用left join
,一切還是要以實際業務為主,所以大家還是仁者見仁智者見智的選擇吧。博主這裡因為業務並不是很需要left join
,所以果斷選擇使用inner join
來連線表。
三、關於 left join的優化
根據上面我們們的對比,基本可以總結出來一些簡單的優化方案。
1、left join選擇小表作為驅動表(這部分基本是大家的共識)
2、如果左表比較大,並且業務要求驅動表必須是左表,那麼我們可以通過where條件語句,使得左表被過濾的小一些,主要原理和第一條類似
3、關聯欄位給索引,因為在mysql的巢狀迴圈演算法中,是通過關聯欄位進行關聯,並查詢的,所以給關聯欄位索引很必要
4、如果sql裡面有排序,請給排序欄位加上索引,不然會造成排序使用全表掃描
參考:https://www.oschina.net/question/930697_2190172
5、如果where條件中含有右表的非空條件(除開is null),則left join語句等同於join語句,可直接改寫成join語句。
6、根據文件,MySQL能更高效地在宣告具有相同型別和尺寸的列上使用索引。所以把表與表之間的關聯欄位給上encoding和collation(決定字元比較的規則)全部改成統一的型別
7、右表的條件列一定要加上索引(主鍵、唯一索引、字首索引等),最好能夠使type達到range及以上(ref,eq_ref,const,system)
注意: 此處的5、6、7參考部落格:https://luxuryzh.iteye.com/blog/1976004 ,這個部落格總結的很好,強烈推薦
推薦部落格閱讀:
博主在查過各種資料之後,最終把自己的連線型別改為了inner join
,並且給關聯欄位以及排序欄位都加上了索引,速度比起剛開始的時候確實是快了不少。只是說mysql還有很多需要研究的地方,加油吧,碰到並解決,不虧~
end
相關文章
- mysql left join轉inner joinMySql
- MySQL LEFT JOIN/ INNER JOIN/RIGHT JOINMySql
- Inner Join, Left Outer Join和Association的區別
- mysql中的left join、right join 、inner join的詳細用法MySql
- join、inner join、left join、right join、outer join的區別
- left join,right join,inner join的條件on和where的區別
- sql之left join、right join、inner join的區別SQL
- sql的left join 、right join 、inner join之間的區別SQL
- mysql left join 優化學習MySql優化
- SQL中聯表查詢操作(LEFT JOIN, RIGHT JOIN, INNER JOIN)SQL
- mysql + left joinMySql
- sql中的join、left join、right joinSQL
- NOT IN、JOIN、IS NULL、NOT EXISTS效率對比Null
- LEFT JOIN 和JOIN 多表連線
- sql:left join和join區別SQL
- mysql update join優化update in查詢效率MySql優化
- 【MySQL】LEFT JOIN 踩坑MySql
- 用LEFT JOIN優化標量子查詢優化
- sql left join 和 right join解釋SQL
- MySql的join(連線)查詢 (三表 left join 寫法)MySql
- sql的 INNER JOIN 語法SQL
- Mysql-left join on後接and,和where的區別MySql
- oracle的left join,right join和full join的一點介紹(R1)Oracle
- Oracle資料庫聯接(inner join ,outer join)和NOT IN的特殊情況Oracle資料庫
- MySQL 之 LEFT JOIN 避坑指南MySql
- Mysql join 的本質,Nested Loop Join 和 Hash JoinMySqlOOP
- MySQL INNER JOIN關聯多張表的寫法MySql
- SQL Server Left joinSQLServer
- 連線查詢簡析 join 、 left join 、 right join
- MySQL系列6 - join語句的優化MySql優化
- 對Hash Join的一次優化優化
- MYSQL 怎麼 LEFT JOIN 多表聯查MySql
- sql的left join 命令詳解SQL
- 【SQL】13 SQL 別名、SQL 連線(JOIN)、SQL INNER JOIN 關鍵字、SQL LEFT JOIN 關鍵字、SQL RIGHT JOIN 關鍵字、SQL FULL OUTER JSQL
- MYSQL count標量子查詢改left joinMySql
- SAP ABAP CDS view 裡 INNER JOIN 和 Association 的區別View
- oracle知識整理(1) union和union all的區別,left join和right join的區別(各種join的區別)Oracle
- Oracle優化案例-用left join代替反連線 not in not exists(十)Oracle優化