MySQL的JOIN(二):JOIN原理

錶鏈接算法

Nested Loop Join(NLJ)算法: 
首先介紹一種基礎算法:NLJ,嵌套循環算法。循環外層是驅動表,循壞內層是被驅動表。驅動表會驅動被驅動表進行鏈接操做。首先驅動表找到第一條記錄,而後從頭掃描被驅動表,逐一查找與驅動表第一條記錄匹配的記錄而後鏈接起來造成結果表中的一條記。被驅動表查找完後,再從驅動表中取出第二個記錄,而後從頭掃描被驅動表,逐一查找與驅動表第二條記錄匹配的記錄,鏈接起來造成結果表中的一條記錄。重複上述操做,直到驅動表的所有記錄都處理完畢爲止。這就是嵌套循環鏈接算法的基本思想,僞代碼以下。算法

foreach row1 from t1
        foreach row2 from t2
            if row2 match row1 //row2與row1匹配,知足鏈接條件
                join row1 and row2 into result //鏈接row1和row2加入結果集

首先加載t1,而後從t1中取出第一條記錄,以後加載t2表,與t2表中的記錄逐個匹配,鏈接匹配的記錄。緩存

Block Nested Loop Join(BNLJ)算法: 
再介紹一種高級算法:BNLJ,塊嵌套循環算法,能夠看做對NLJ的優化。大體思想就是創建一個緩存區,一次從驅動表中取多條記錄,而後掃描被驅動表,被驅動表的每一條記錄都嘗試與緩衝區中的多條記錄匹配,若是匹配則鏈接並加入結果集。緩衝區越大,驅動表一次取出的記錄就越多。這個算法的優化思路就是減小內循環的次數從而提升錶鏈接效率。oop

影響性能的因素

1.內循環的次數:如今考慮這麼一個場景,當t1有100條記錄,t2有10000條記錄。那麼,t1驅動t2與t2驅動t1,他們之間在效率上孰優孰劣?若是是單純的分析指令執行次數,他們都是100*10000,可是考慮到加載表的次數呢。首先分析t1驅動t2,t1表加載1次,t2表須要加載100次。而後分析t2驅動t1,t2表首先加載1次,可是t1表要加載10000次。因此,t1驅動t2的效率要優於t2驅動t1的效率。由此得出,小表驅動大表可以減小內循環的次數從而提升鏈接效率。 
另外,若是使用Block Nested Loop Join算法的話,經過擴大一次緩存區的大小也能減少內循環的次數。由此又可得,設置合理的緩衝區大小可以提升鏈接效率性能

2.快速匹配:掃描被驅動表尋找合適的記錄能夠看作一個查詢操做,如何提升查詢的效率呢?建索引啊!由此還可得出,在被驅動表創建索引可以提升鏈接效率優化

3.排序:假設t1表驅動t2表進行鏈接操做,鏈接條件是t1.id=t2.id,並且要求查詢結果對id排序。如今有兩種選擇,方式一[...ORDER BY t1.id],方式二[...ORDER BY t2.id]。若是咱們使用方式一的話,能夠先對t1進行排序而後執行錶鏈接算法,若是咱們使用方式二的話,只能在執行錶鏈接算法後,對結果集進行排序(Using temporary),效率天然低下。由此最後可得出,優先選擇驅動表的屬性進行排序可以提升鏈接效率。spa

相關文章
相關標籤/搜索