1、多表查詢鏈接的選擇:
相信這內鏈接,左鏈接什麼的你們都比較熟悉了,固然還有左外鏈接什麼的,基本用不上我就不貼出來了。這圖只是讓你們回憶一下,各類鏈接查詢。 而後要告訴你們的是,須要根據查詢的狀況,想好使用哪一種鏈接方式效率更高。mysql
2、MySQL的JOIN實現原理
在MySQL 中,只有一種Join 算法,就是大名鼎鼎的Nested Loop Join,他沒有其餘不少數據庫所提供的Hash Join,也沒有Sort Merge Join。顧名思義,Nested Loop Join 實際上就是經過驅動表的結果集做爲循環基礎數據,而後一條一條的經過該結果集中的數據做爲過濾條件到下一個表中查詢數據,而後合併結果。若是還有第三個參與Join,則再經過前兩個表的Join 結果集做爲循環基礎數據,再一次經過循環查詢條件到第三個表中查詢數據,如此往復。 ——摘自《MySQL 性能調優與架構設計》laravel
3、補充:mysql對sql語句的容錯問題
即在sql語句不徹底符合書寫建議的狀況,mysql會容許這種狀況,儘量解釋它:面試
1)通常cross join後面加上where條件,可是用cross join+on也是被解釋爲cross join+where;算法
2)通常內鏈接都須要加上on限定條件,如上面場景一;若是不加會被解釋爲交叉鏈接;sql
3)若是鏈接表格使用的是逗號,會被解釋爲交叉鏈接;shell
注:sql標準中還有union join和natural inner join,mysql不支持,並且自己也沒有多大意義,其實就是爲了「健壯」。可是其實結果能夠用上面的幾種鏈接方式獲得。數據庫
3、超大型數據儘量盡力不要寫子查詢,使用鏈接(JOIN)去替換它:
固然,關於這句話,也不必定就全是這樣。服務器
1)由於在大型的數據處理中,子查詢是很是常見的,特別是在查詢出來的數據須要進一步處理的狀況,不管是可讀性仍是效率上,這時候的子查都是更優。架構
2)然而在一些特定的場景,能夠直接從數據庫讀取就能夠的,好比一個表(A表 a,b,c字段,須要內部數據交集)join本身的效率必然比放一個子查在where中快得多。併發
4、使用聯合(UNION)來代替手動建立的臨時表
UNION是會把結果排序的!!!
union查詢:它能夠把須要使用臨時表的兩條或更多的select查詢合併的一個查詢中(即把兩次或屢次查詢結果合併起來。)。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證數據庫整齊、高效。使用union來建立查詢的時候,咱們只須要用UNION做爲關鍵字把多個select語句鏈接起來就能夠了,要注意的是全部select語句中的字段數目要想同。
要求:兩次查詢的列數必須一致(列的類型能夠不同,但推薦查詢的每一列,相對應的類型要同樣)
能夠來自多張表的數據:屢次sql語句取出的列名能夠不一致,此時以第一個sql語句的列名爲準。
若是不一樣的語句中取出的行,有徹底相同(這裏表示的是每一個列的值都相同),那麼union會將相同的行合併,最終只保留一行。也能夠這樣理解,union會去掉重複的行。
若是不想去掉重複的行,可使用union all。
若是子句中有order by,limit,需用括號()包起來。推薦放到全部子句以後,即對最終合併的結果來排序或篩選。
注意:
一、UNION 結果集中的列名老是等於第一個 SELECT 語句中的列名
二、UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有類似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同
UNION ALL的做用和語法:
默認地,UNION 操做符選取不一樣的值。若是容許重複的值,請使用 UNION ALL。當 ALL 隨 UNION 一塊兒使用時(即 UNION ALL),不消除重複行。
5、總結
(1)對於要求全面的結果時,咱們須要使用鏈接操做(LEFT JOIN / RIGHT JOIN / FULL JOIN);
(2)應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描,如:
備註、描述、評論之類的能夠設置爲 NULL,其餘最好不要使用NULL。
不要覺得 NULL 不須要空間,好比:char(100) 型,在字段創建時,空間就固定了, 不論是否插入值(NULL也包含在內),都是佔用 100個字符的空間的,若是是varchar這樣的變長字段, null 不佔用空間。
能夠在num上設置默認值0,確保表中num列沒有null值,而後這樣查詢:
select id from t where num = 0
(3)in 和 not in 也要慎用,不然會致使全表掃描,如:
對於連續的數值,能用 between 就不要用 in 了:
不少時候用 exists 代替 in 是一個好的選擇:
(4)儘可能使用數字型字段,若只含數值信息的字段儘可能不要設計爲字符型,這會下降查詢和鏈接的性能,並會增長存儲開銷。這是由於引擎在處理查詢和連 接時會逐個比較字符串中每個字符,而對於數字型而言只須要比較一次就夠了。
(5)儘可能使用表變量來代替臨時表。若是表變量包含大量數據,請注意索引很是有限(只有主鍵索引)。
(6)不要覺得使用MySQL的一些鏈接操做對查詢有多麼大的改善,其實核心是索引
以上內容但願幫助到你們, 不少PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那裏入手去提高,對此我整理了一些資料,包括但不限於:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨須要的能夠免費分享給你們 ,須要戳這裏 PHP進階架構師>>>實戰視頻、大廠面試文檔免費獲取