天天看點

MySQL_MySQL查詢截取分析之小表驅動大表

1.引入

  我們之前和大家講解了索引的基本内容以及索引的優化,那麼下面呢我們就進入我們的下一個部分的内容:查詢截取分析。我們在使用我們的MySQL進行實際操作的時候,是如何進行MySQL資料庫優化查詢的分析呢?一般我們都會經過如下的步驟:

(1).運作系統,觀察一段時間(一般需要大于1天),看看執行慢的SQL情況。

(2).開啟慢查詢日志。通過這隻執行的門檻值,如執行時間超過幾秒的就定義為慢SQL(具體幾秒按照系統的情況而定),并把它抓取出來。

(3).使用explain + 慢SQL分析。

一般的情況,我們通過上述的操作以後就基本可以查詢出SQL中存在的問題了。但是如果還沒有解決問題。那麼這一個時候我們就需要更加深入的進行分析。

(4).show profile。(這一個操作一般就是運維經理或者是DBA,來進行SQL資料庫伺服器的參數優化)。

2.小表驅動大表

   為什麼說在資料庫中的操作是需要小表來驅動大表?好,我們呢一起來看一下的這一個操作:

//一個簡單的嵌套循環(A)

for(int i = 0 ; i < 100; i ++)
{
  for(int j  = 0 ; j < 20; j ++)
  {
    System.out.println("Hello world");
  }

}

//另一個簡單的嵌套循環(B)

for(int i = 0 ; i < 20; i ++)
{
  for(int j  = 0 ; j < 100; j ++)
  {
    System.out.println("Hello world");
  }

}

分析:
    倆個程式的輸出結果都是一樣的,在一般的Java程式中沒有多大的差別,但是在MySQL的執行中卻有較大的差別!,為什麼呢?
    我們可以這樣了解這一個問題。我們使用java程式去操作資料庫内容,我們需要和資料庫建立連接配接的通道,查詢完畢以後,我們需要再次關閉資料庫的連接配接。但是呢如果說在較短的時間需要和資料庫建立很多次的連接配接,但是你每一次連接配接都隻做了一個簡單的查詢。這一個時候你就會占用MySQL資料庫的資源。但是其達到的效果确是很低的。但是你反過來,一個連接配接我們就能夠在MySQL資料庫上進行很多的操作。那麼這樣我們就把MySQL的資源充分的利用起來了。這就是為什麼需要小表驅動大表。
           

3.小表驅動大表的使用:in關鍵字和exists關鍵字的相關使用:

(1).建立資料庫表:

  圖書庫存表(bookstore)

MySQL_MySQL查詢截取分析之小表驅動大表

圖書資訊表(book)

MySQL_MySQL查詢截取分析之小表驅動大表

倆表通過字段bookstore_id進行關聯。

(2).使用In關鍵字進行倆表的查詢

MySQL_MySQL查詢截取分析之小表驅動大表
SQL:

select * from book where bookstore_id in(select bookstore_id from bookstore);

等價于:

for : select bookstore_id from bookstore;

for : select * from book where book.bookstore_id = bookstore.bookstore_id;
           

(3).使用exists關鍵字進行倆表的查詢

MySQL_MySQL查詢截取分析之小表驅動大表
SQL:

select * from book where exists (select 1 from bookstore where bookstore.bookstore_id = book.bookstore_id);

等價于:

for:  select * from book;

for:  select * from bookstore where bookstore.bookstore_id = book.bookstore_id;


這個文法可以這樣了解:
    将主查詢的資料,放到子查詢中做條件驗證。根據驗證的結果(true或者是false)來決定查詢的資料是否可以保留。
           

(4).使用in關鍵字或者是exists哪一種更加好呢?

當bookstore表的資料集必須小于book表的資料集時,使用in優于exists。

當book表的資料集必須小于bookstore表的資料集時,使用exists優于in。

同時,我們應該在book表和bookstore表的bookstore_id 上建立相關的索引。

(5).總結:

①.exists關鍵字的查詢隻傳回一個布爾類型的資料(true/false).這樣就導緻select * 也可以是select + 常量。或者是是實際執行的時候會忽略select清單。是以是沒有差別的。

②.exists關鍵字子查詢的實際執行過程可能會經過優化,而不是我們了解的逐條對比。如擔心效率的問題。可以進行實際驗證确定是否有效。

③..exists關鍵字子查詢往往可以使用條件表達式、其他子查詢或者是JOIN來替代。