Multi-Range Read (MRR)原理
Multi-Range Read (MRR)
MRR?的全稱是?Multi-Range Read Optimization,是優化器將隨機?IO?轉化為順序?IO?以降低查詢過程中?IO?開銷的一種手段,這對IO-bound類型的SQL語句性能帶來極大的提升,適用于range ref eq_ref類型的查詢
MRR優化的幾個好處
使數據訪問有隨機變為順序,查詢輔助索引是,首先把查詢結果按照主鍵進行排序,按照主鍵的順序進行書簽查找
減少緩沖池中頁被替換的次數
批量處理對鍵值的操作
在沒有使用MRR特性時
第一步 先根據where條件中的輔助索引獲取輔助索引與主鍵的集合,結果集為rest
| 1 | select?key_column, pk_column from tb where key_column=x order by key_column |
第二步 通過第一步獲取的主鍵來獲取對應的值
| 1 2 | for?each pk_column valuein?restdo: select?non_key_column from tb where pk_column=val |
使用MRR特性時
第一步 先根據where條件中的輔助索引獲取輔助索引與主鍵的集合,結果集為rest
| 1 | select?key_column, pk_column from tb where key_column = x order by key_column |
第二步 將結果集rest放在buffer里面(read_rnd_buffer_size?大小直到buffer滿了),然后對結果集rest按照pk_column排序,得到結果集是rest_sort
第三步 利用已經排序過的結果集,訪問表中的數據,此時是順序IO.
| 1 | select?non_key_column fromtb where pk_columnin?(rest_sort) |
在不使用?MRR?時,優化器需要根據二級索引返回的記錄來進行“回表”,這個過程一般會有較多的隨機IO,?使用MRR時,SQL語句的執行過程是這樣的:
-
優化器將二級索引查詢到的記錄放到一塊緩沖區中
-
如果二級索引掃描到文件的末尾或者緩沖區已滿,則使用快速排序對緩沖區中的內容按照主鍵進行排序
-
用戶線程調用MRR接口取cluster index,然后根據cluster index?取行數據
-
當根據緩沖區中的?cluster index取完數據,則繼續調用過程?2) 3),直至掃描結束
通過上述過程,優化器將二級索引隨機的?IO?進行排序,轉化為主鍵的有序排列,從而實現了隨機?IO?到順序?IO?的轉化,提升性能
此外MRR還可以將某些范圍查詢,拆分為鍵值對,來進行批量的數據查詢,如下:
SELECT * FROM t WHERE?key_part1?>= 1000 AND?key_part1?< 2000AND?key_part2?= 10000;
表t上有二級索引(key_part1, key_part2),索引根據key_part1,key_part2的順序排序。
若不使用MRR:此時查詢的類型為Range,sql優化器會先將key_part1大于1000小于2000的數據取出,即使key_part2不等于10000,帶取出之后再進行過濾,會導致很多無用的數據被取出
若使用MRR:如果索引中key_part2不為10000的元組越多,最終MRR的效果越好。優化器會將查詢條件拆分為(1000,1000),(1001,1000),...?(1999,1000)最終會根據這些條件進行過濾
相關參數
當mrr=on,mrr_cost_based=on,則表示cost base的方式還選擇啟用MRR優化,當發現優化后的代價過高時就會不使用該項優化
當mrr=on,mrr_cost_based=off,則表示總是開啟MRR優化
| 1 | SET? @@optimizer_switch='mrr=on,mrr_cost_based=on'; |
參數read_rnd_buffer_size?用來控制鍵值緩沖區的大小。二級索引掃描到文件的末尾或者緩沖區已滿,則使用快速排序對緩沖區中的內容按照主鍵進行排序
總結
以上是生活随笔為你收集整理的Multi-Range Read (MRR)原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql ICP优化的原理
- 下一篇: 判断一个数是否是2的幂