天天看點

MySQL join buffer使用

對于join buffer實作,于是做了以下實驗:

   從sql的執行計劃中我們可以看到mysql使用using join buffer算法來優化改sql的查詢,那麼他的原理是什麼?又是怎麼樣來實作的?在sql中注意到我加了hint提示符straight_join讓,強制mysql按照查詢中出現的順序來連接配接表,意思是讓t1表作為驅動表,t1中有多少記錄,那麼就要對t2表關聯多少次(由于t2表為為我們子查詢中的結果集,mysql在處理子查詢的時候,把他子查詢的結果放到臨時表中,把臨時表當做普通通進行處理,也就是執行計劃中出現derived2,注意這裡的臨時表不在有id的索引了);

那麼t2表就被多次的掃描,如果t2表的結果集非常的大,那麼就會造成性能上的問題,是以mysql在這裡對其進行了優化,采用Block Nested-Loop Join (BNL),具體算法描述為:

for each row in t1 matching range {

for each row in t2 matching reference key {

store used columns from t1, t2 in join buffer    if buffer is full {

flush_buffer();

}

empty buffer

flush_buffer() {

for each row in t3 {

for each t1, t2 combination in join buffer {

if row satisfies join conditions,      send to client

從圖中可以看到把t1和t2的結果集放到join buffer中,而不用每次t1和t2關聯後馬上有和t3關聯,這也是沒有必要的,然後隻需一次掃描t3即可完成這個查詢;需要注意的是join buffer中隻保留查詢結果中出現的列值,它的大小不依賴于表的大小,我們在僞代碼中看到當join buffer被填滿後,mysql将會flush buffer。

 注意:Join Buffer 隻有當我們的 Join 類型為 ALL(如示例中),index,rang 或者是 index_merge 的時候 才能夠使用