一文搞懂MySQL的Join

2021-09-25 21:56:17 字數 1605 閱讀 9430

經常聽到2種觀點:

其實對於上面的觀點一定程度上是正確的,但不是完全正確。但之所以流傳這麼廣,主要還是沒有搞清楚實際狀態,而根據實際使用中總結出來的一些模糊規律。只有了解的mysql的join實際執行方式,就會知道上面2種觀點是一種模糊的規律,這種規律並不能指導我們實際開發。下面就說說mysql的實際join執行方式。

join可以說一種集合的運算,比如left join,right join,inner join,full join,outer join,cross join等,這些集合間的計算關係對應在高中數學集合裡面的交集,並集,補集,全集等。但在實際的**中,join運算基本上是通過多層迴圈來實現的。

舉乙個例子,假設有t1,t2兩張表,表結構分別如下:

create table t1 (

id int not null auto_increment,

username varchar(20) not null default ,

age int not null default 0,

primary key (`id`)

)engine=innodb default charset=utf8mb4  ;

create table t2(

id int not null auto_increment,

username varchar(20) not null default ,

score int not null de****t 0,

primary key (`id`)

))engine=innodb default charset=utf8mb4;

假設t1有100條資料,t2表有200條數

查詢sql為:

select t1.*,t2.* from t1 left join t2 on(t1.username=t2.username)

那麼這條sql的執行步驟如下:

基本上先遍歷t,1,然後根據t1中的每行資料中的username,去表t2中查詢滿足條件的記錄。基本就是2層迴圈。

從上面可以看出,join本質是迴圈,這裡的開銷如下:

遍歷t1資料,讀取資料為t1表的行數,假設行數為n,則複雜度也為n

根據t1的匹配欄位username去t2中一行一行的查詢資料

這個過程,因為mysql的資料儲存結構為二叉樹,時間複雜度為log2(m) m為t2表的總行數

那麼總複雜度近似為 n+n(2log2(m))

從上面的步驟可以看出,優化方向:

優化的基本方法:

其實mysql針對上面的優化方法有對應的演算法:

從上面的分析我們可以看到,用join還是可行的,只要效能可控且在接受範圍內,還是能減少**複雜度的。需要避免的是join的表沒有索引,不然這樣的sql發線上是災難性的。

join還是可以大膽的使用,只要把握好幾個原則:

一文搞懂MySQL字首索引

通常在開發中我們需要定義字串型別的字段,例如使用者名稱或者使用者郵箱等。假設我們在維護乙個使用者登入系統,使用者表的定義 create table user id bigint unsigned primary key,email varchar 64 engine innodb 如果使用郵箱登入的...

一文搞懂MySQL預編譯

1 預編譯的好處 大家平時都使用過jdbc中的preparedstatement介面,它有預編譯功能。什麼是預編譯功能呢?它有什麼好處呢?當客戶傳送一條sql語句給伺服器後,伺服器總是需要校驗sql語句的語法格式是否正確,然後把sql語句編譯成可執行的函式,最後才是執行sql語句。其中校驗語法,和編...

一文搞懂transform skew

目錄 如何理解斜切 skew,先看乙個 demo。在下面的 demo 中,有 4 個正方形,分別是 紅色 不做 skew 變換,綠色 x 方向變換,藍色 y 方向變換,黑色 兩個方向都變換,拖動下面的滑塊可以檢視改變 skew 角度後的效果。切換 selector 可以設定 transform or...