Java之道丨左連接left join 右連接right join 內連接inner join

最近,公司的用戶達到了700+萬,意味著數據庫已經達到700+萬,聊聊傻傻分不清的連接查詢吧!

前提:數據庫中一共有三個表:class,book,phone,而且每個數據庫表中都有10萬條數據,三個表一共有30萬條數據,從大數據量的角度來檢測你寫的sql語句性能是如何的.

一.左連接

Java之道丨左連接left join 右連接right join 內連接inner join

left join 是left outer join的簡寫,它的全稱是左外連接,是外連接中的一種。

注:左(外)連接,左表(a_table)的記錄將會全部表示出來,而右表(b_table)只會顯示符合搜索條件的記錄。右表記錄不足的地方均為NULL。

用sql語句查詢前10000條數據,sql語句表示如下:

select * from class LEFT JOIN book on class.card=book.card limit 10000

查詢時間為:

Java之道丨左連接left join 右連接right join 內連接inner join

用explain檢測性能,語句為:

EXPLAIN

select * from class LEFT JOIN book on class.card=book.card limit 10000

其結果:

Java之道丨左連接left join 右連接right join 內連接inner join

從此我們可以看出兩個的type都是all ,其中class表需要檢測的行數是100398,book表需要檢測的行數是100453,可以看出這是一個多麼大的工程.

往book表中插入索引:

  1. ALTER TABLE `book` ADD INDEX y ( `card`);

其結果為:

查詢時間為:

Java之道丨左連接left join 右連接right join 內連接inner join

查詢速度是沒有添加索引時的31.6倍,那麼再來看看它的性能

Java之道丨左連接left join 右連接right join 內連接inner join

從結果中,我們可以看出第二行的type變成了ref ,其中rows也從原來的100453變成了523.優化的比較明顯.left join條件用於確定如何從右表搜索行,左邊一定都有,所以右邊是我們的關鍵點,一定需要建立索引.

刪除舊索引,建立class表的新索引

  1. DROP INDEX y ON book;
  2. ALTER TABLE `class` ADD INDEX x ( `card`);

SQL語句執行所需要的時間:

Java之道丨左連接left join 右連接right join 內連接inner join

查詢時間和未添加索引的時候索引值差不錯.

那看看性能:

Java之道丨左連接left join 右連接right join 內連接inner join

Class表的type變成了index,還是很糟糕的,而且兩個表的rows都是100453,這還是一個很大工程.

二.右連接

Java之道丨左連接left join 右連接right join 內連接inner join

right join是right outer join的簡寫,它的全稱是右外連接,是外連接中的一種

注:右(外)連接,左表(a_table)只會顯示符合搜索條件的記錄,而右表(b_table)的記錄將會全部表示出來。左表記錄不足的地方均為NULL。

其中還是保持class表中的card字段建立索引,其sql語句為:

select * from class RIGHT JOIN book on class.card=book.card limit 10000

執行時間為:

Java之道丨左連接left join 右連接right join 內連接inner join

其性能為:

Java之道丨左連接left join 右連接right join 內連接inner join

優化較明顯,這是因為Right join是先執行book表,在執行class表格,right join條件用於確定如何從左表搜索行,右邊一定都有,所以左邊是我們的關鍵點,一定需要建立索引.

刪除就索引,在book表中建立新索引:

  1. DROP INDEX y ON book;
  2. ALTER TABLE `book` ADD INDEX y ( `card`);

其sql語句查詢時間為:

Java之道丨左連接left join 右連接right join 內連接inner join

其sql語句性能:

Java之道丨左連接left join 右連接right join 內連接inner join

其情況和兩個表都不添加索引的沒有多大的變化.

三.內連接

Java之道丨左連接left join 右連接right join 內連接inner join

組合兩個表中的記錄,返回關聯字段相符的記錄,也就是返回兩個表的交集(陰影)部分。

注:組合兩個表中的記錄,返回關聯字段相符的記錄,也就是返回兩個表的交集(陰影)部分。

最後來看看inner join的情況,其book表的card字段建立了索引,class表未建立索引,其sql語句:

select * from class INNER JOIN book on class.card=book.card limit 10000

sql語句執行時間:


Java之道丨左連接left join 右連接right join 內連接inner join

其性能:

Java之道丨左連接left join 右連接right join 內連接inner join

再在class表中建立索引試試:

  1. ALTER TABLE `class` ADD INDEX x ( `card`);

其查詢時間為:

Java之道丨左連接left join 右連接right join 內連接inner join

查詢時間沒有多大變化,但是sql語句的性能呢?

Java之道丨左連接left join 右連接right join 內連接inner join

結果是沒有多大的變化.

從以上的測試我們可以得出:

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

查詢時間:

Java之道丨左連接left join 右連接right join 內連接inner join

還在可以接受的範圍內.

其性能:

Java之道丨左連接left join 右連接right join 內連接inner join

從結果可以看出,結果並不太理想.再來看看添加索引的情況

分別給phone表和book表,class表添加索引,sql語句如下:

  1. ALTER TABLE `class` ADD INDEX x ( `card`);
  2. ALTER TABLE `phone` ADD INDEX z ( `card`);
  3. ALTER TABLE `book` ADD INDEX y ( `card`);

查詢時間為:

Java之道丨左連接left join 右連接right join 內連接inner join

其性能為:

Java之道丨左連接left join 右連接right join 內連接inner join

最後兩行的type都是ref ,且rows的值是500左右,優化效果還是很不錯的.

在建立數據的初期,可以根據業務的需要,適當的建立索引還是很有必要的,適當的索引可以大大提高sql語句的性能.

Java之道丨左連接left join 右連接right join 內連接inner join


分享到:


相關文章: