一、典型回答
? 之所以不建議使用JOIN查詢,最主要的原因就是JOIN的效率比較低。
? MySQL是使用了嵌套循環(Nested-Loop Join)的方式實現關聯查詢的,簡單點說就是要通過兩層循環,用第一張表做外循環,第二張表做內循環,外循環的每條記錄跟內循環中的記錄作比較,符合條件的就輸出。
? 而具體到算法實現上主要是simpl nested loop,block nested loop和index nested loop這三種。而且這三種的效率都沒有特別高的。
? MySQL使用了嵌套循環(Nested-Loop Join)的方式來實現關聯查詢的,如果有2張表JOIN的話,復雜度最高是O(n^2),3張表則是O(n^3)...隨著表越多,表中的數據量越多,JOIN的效率會呈指數級下降。
二、JOIN
? 在MySQL中,可以使用JOIN在兩個或多個表中進行聯合查詢,JOIN有三種,分別是INNER?JOIN、LEFT?JOIN、RIGHT?JOIN。
? INNER?JOIN(內連接或等值連接):獲取兩個表中字段匹配關系的記錄,取兩個表的交集部分。
? LEFT?JOIN(左連接):獲取左表左右記錄,即使右表沒有對應匹配的記錄,取兩個表的交集部分+左表中的數據。
? RIGHT?JOIN(右連接):與LEFT?JOIN相反,用戶獲取右表所有記錄,即使左表沒有對應匹配的記錄,取兩個表的交集部分+右表中的數據。
三、嵌套循環算法
? MySQL使用了嵌套循環(Nested-Loop Join)的方法來實現關聯查詢的,simpl nested loop,block nested loop和index nested loop三種。
??simpl nested loop:他的做法簡單粗暴,就是全量掃描連接兩張表進行數據的兩兩對比,所以他的復雜度可以認為是N*M(N是驅動表的數量,M是被驅動表的數量)。
??block nested loop:當inner loop的表用到字段來索引的話,可以用到索引進行查詢數據,因為索引是B+樹的,復雜度可以近似認為是N*logM。
??index nested loop:引入了BUFFER,會提前把外循環的一部分結果放到JOIN BUFFER中然后內循環的每一行都和整體BUFFER的數據作比較,索然比較次數還是N*M,但是因為JOIN BUFFER是基于內存的,所以效率高很多。
? 所以,雖然MySQL已經盡可能的在優化了,但是這幾種算法復雜度還是挺高的,這也是說為什么不建議在數據庫中多表JOIN的原因,隨著表越多,表中的數據量越多,JOIN的效率會呈指數級下降。
四、不能用JOIN如何做關聯查詢
? 如果不能通過數據庫在關聯查詢,那么需要查詢多表數據的時候要怎么做呢?
? 主要有兩種方法:
? ? 1、在內存中自己做關聯,即先從數據庫中把數據查出來之后,在代碼中進行二次查詢,然后再進行關聯。
? ? 2、數據冗余,那就把一些重要的數據在表中做冗余,這樣就可以避免關聯查詢了。
? ? 3、寬表,就是基于一定的JOIN關系,把數據庫中多張表的數據打平做一張大寬表,可以同步到ES或者干脆直接在數據庫中直接查出來。
參考:Hollis