MySQL Query 的優化—Join的實現原理及優化思路

Join 的實現原理

在尋找 Join 語句的優化思路之前,我們首先要理解在 MySQL 中是如何來實現 Join 的,只要理解了實現原理之後,優化就比較簡單了。

在 MySQL 中,只有一種 Join 算法,就是大名鼎鼎的 Nested Loop Join,Nested Loop Join 實際上就是通過驅動表的結果集作爲循環基礎數據,然後一條一條的通過該結果集中的數據作爲過濾條件到下一個表中查詢數據,然後合併結果。如果還有第三個參與 Join,則再通過前兩個表的 Join 結果集作爲循環基礎數據,再一次通過循環查詢條件到第三個表中查詢數據,如此往復。

Join 語句的優化
1. 儘可能減少 Join 語句中的 Nested Loop 的循環總次數;
如何減少 Nested Loop 的循環總次數?最有效的辦法只有一個,那就是讓驅動表的結果集儘可能的小,這也正是在本章第二節中的優化基本原則之一“永遠用小結果集驅動大的結果集”。

當然,此優化的前提條件是通過 Join 條件對各個表的每次訪問的資源消耗差別不是太大。如果訪問存在較大的差別的時候(一般都是因爲索引的區別),我們就不能簡單的通過結果集的大小來判斷需要 Join 語句的驅動順序,而是要通過比較循環次數和每次循環所需要的消耗的乘積的大小來得到如何驅動更優化。

  1. 優先優化 Nested Loop 的內層循環;

  2. 保證 Join 語句中被驅動表上 Join 條件字段已經被索引;

  3. 當無法保證被驅動表的 Join 條件字段被索引且內存資源充足的前提下,不要太吝惜 JoinBuffer 的設置;

join_buffer

join_buffer_size在mysql官方文檔只說明瞭用於連接的buffer大小,
1,join buffer究竟是存放的什麼數據?
2,爲什麼不使用標準的cache,而對於join操作要單獨設置一個buffer?
再來看nest loop的處理過程,由於第二個表可能需要訪問多次,可能造成的一個後果就是第二個表對的cache會非常熱,從而形成熱塊,在多個線程執行連接同時去訪問相應的的cache時,帶來的影響越大. 使用了一個專用的join buffer來存放第二個表以後,至少可以解決以下問題:
1,由於join buffer是存放的基於每thread的連接表信息,這樣在連接的時候,只需要訪問join buffer就可以了,不需要再去有併發機制保護的cache.
2,join buffer的代碼路徑更短,執行訪問速度更快.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章