Mysql中Join用法及優化


Join的幾種類型

 

笛卡爾積(交叉連接) 

如果A表有n條記錄,B表有m條記錄,笛卡爾積產生的結果就會產生n*m條記錄
在MySQL中可以為CROSS JOIN或者省略CROSS即JOIN,或者直接用from多表用逗號分開。
如 

SELECT * FROM table1 CROSS JOIN table2 
SELECT * FROM table1 JOIN table2 
SELECT * FROM table1 , table2

不用on table1.key1 = table2.key2 得出的結果是table1的記錄數*table2的記錄數,如果用on連接,得出的和inner join的結果一樣(所以在有on的情況下,inner joijn、cross join、 join(推薦、會自動用小的表作為驅動表)結果一樣)。

內連接:INNER JOIN

內連接INNER JOIN是最常用的連接操作。從數學的角度講就是求兩個表的交集,從笛卡爾積的角度講就是從笛卡爾積中挑出ON子句條件成立的記錄。有INNER JOIN,WHERE(等值連接),STRAIGHT_JOIN,JOIN(省略INNER)四種寫法。

左【外】連接:LEFT [out] JOIN

左連接LEFT JOIN的含義就是求兩個表的交集外加左表剩下的數據。依舊從笛卡爾積的角度講,就是先從笛卡爾積中挑出ON子句條件成立的記錄,然后加上左表中剩余的記錄(見最后三條)。

右【外】連接:RIGHT [out] JOIN

同理右連接RIGHT JOIN就是求兩個表的交集外加右表剩下的數據。再次從笛卡爾積的角度描述,右連接就是從笛卡爾積中挑出ON子句條件成立的記錄,然后加上右表中剩余的記錄(見最后一條)。

全外連接:Full outer join

產生A和B的並集。對於沒有匹配的記錄,則以null做為值。( 注意!!!Orcal有,Mysql是沒有全外連接的!!!可以用做外連接和右外連接在union(union連接的是兩個查詢不是兩張表)起來)
select *,if(a.date is null,b.date,a.date) as date from a left join b on a.date = b.date  -- 只有a的全部
union -- union上面的復制下來left改為right,連個表頭要一致
select *,if(a.date is null,b.date,a.date) as date from a right join b on a.date = b.date

查詢存在於一張表不存在於另一張表的sql

select ta.* from ta where ta.id not in(select tb.id from tb)  /*效率低*/
select ta.id from ta left join tb on ta.id=tb.id where tb.id is NULL  /*優化*/

兩表JOIN優化

     a.當無order by條件時,根據實際情況,使用left/right/inner join即可,根據explain優化 ;
     b.當有order by條件時,如select * from a inner join b where 1=1 and other condition order by a.col;使用explain解釋語句;
     1)如果第一行的驅動表為a,則效率會非常高,無需優化;
     2)否則,因為只能對驅動表字段直接排序的緣故,會出現using temporary,所以此時需要使用 STRAIGHT_JOIN明確a為驅動表,來達到使用a.col上index的優化目的; 或者使用left join且Where條件中不含b的過濾條件,此時的結果集為a的全集, 而STRAIGHT_JOIN為inner join且使用a作為驅動表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM