最近,公司的用戶達到了700+萬,意味著數據庫已經達到700+萬,聊聊傻傻分不清的連接查詢吧!
前提:數據庫中一共有三個表:class,book,phone,而且每個數據庫表中都有10萬條數據,三個表一共有30萬條數據,從大數據量的角度來檢測你寫的sql語句性能是如何的.
一.左連接
注:左(外)連接,左表(a_table)的記錄將會全部表示出來,而右表(b_table)只會顯示符合搜索條件的記錄。右表記錄不足的地方均為NULL。
用sql語句查詢前10000條數據,sql語句表示如下:
select * from class LEFT JOIN book on class.card=book.card limit 10000
查詢時間為:
用explain檢測性能,語句為:
EXPLAIN
select * from class LEFT JOIN book on class.card=book.card limit 10000
其結果:
從此我們可以看出兩個的type都是all ,其中class表需要檢測的行數是100398,book表需要檢測的行數是100453,可以看出這是一個多麼大的工程.
往book表中插入索引:
- ALTER TABLE `book` ADD INDEX y ( `card`);
其結果為:
查詢時間為:
查詢速度是沒有添加索引時的31.6倍,那麼再來看看它的性能
從結果中,我們可以看出第二行的type變成了ref ,其中rows也從原來的100453變成了523.優化的比較明顯.left join條件用於確定如何從右表搜索行,左邊一定都有,所以右邊是我們的關鍵點,一定需要建立索引.
刪除舊索引,建立class表的新索引
- DROP INDEX y ON book;
- ALTER TABLE `class` ADD INDEX x ( `card`);
SQL語句執行所需要的時間:
查詢時間和未添加索引的時候索引值差不錯.
那看看性能:
Class表的type變成了index,還是很糟糕的,而且兩個表的rows都是100453,這還是一個很大工程.
二.右連接
注:右(外)連接,左表(a_table)只會顯示符合搜索條件的記錄,而右表(b_table)的記錄將會全部表示出來。左表記錄不足的地方均為NULL。
其中還是保持class表中的card字段建立索引,其sql語句為:
select * from class RIGHT JOIN book on class.card=book.card limit 10000
執行時間為:
其性能為:
優化較明顯,這是因為Right join是先執行book表,在執行class表格,right join條件用於確定如何從左表搜索行,右邊一定都有,所以左邊是我們的關鍵點,一定需要建立索引.
刪除就索引,在book表中建立新索引:
- DROP INDEX y ON book;
- ALTER TABLE `book` ADD INDEX y ( `card`);
其sql語句查詢時間為:
其sql語句性能:
其情況和兩個表都不添加索引的沒有多大的變化.
三.內連接
注:組合兩個表中的記錄,返回關聯字段相符的記錄,也就是返回兩個表的交集(陰影)部分。
最後來看看inner join的情況,其book表的card字段建立了索引,class表未建立索引,其sql語句:
select * from class INNER JOIN book on class.card=book.card limit 10000
sql語句執行時間:
其性能:
再在class表中建立索引試試:
- ALTER TABLE `class` ADD INDEX x ( `card`);
其查詢時間為:
查詢時間沒有多大變化,但是sql語句的性能呢?
結果是沒有多大的變化.
從以上的測試我們可以得出:
inner join和 left join差不多,都需要優化右表。而 right join需要優化左表。
四.三表連接
那三個表又該如何優化呢?三個都無索引的時候,sql查詢語句如下:
select * from class
left join book on class.card=book.card
left join phone on book.card = phone.card
limit 10000
查詢時間:
還在可以接受的範圍內.
其性能:
從結果可以看出,結果並不太理想.再來看看添加索引的情況
分別給phone表和book表,class表添加索引,sql語句如下:
- ALTER TABLE `class` ADD INDEX x ( `card`);
- ALTER TABLE `phone` ADD INDEX z ( `card`);
- ALTER TABLE `book` ADD INDEX y ( `card`);
查詢時間為:
其性能為:
最後兩行的type都是ref ,且rows的值是500左右,優化效果還是很不錯的.
在建立數據的初期,可以根據業務的需要,適當的建立索引還是很有必要的,適當的索引可以大大提高sql語句的性能.
閱讀更多 天之道居 的文章