SET @@optimizer_switch='mrr=on,mrr_cost_based=on'; 參數read_rnd_buffer_size 用來控制鍵值緩沖區的大小。二級索引掃描到文件的末尾或者緩沖區已滿,則使用快速排序對緩沖區中的內容按照主鍵進行排序
適用場景 #輔助索引key_part1,查詢key_part1在1000到2000范圍內的數據
SELECT * FROM t WHERE key_part1 >= 1000 AND key_part1 < 2000
不使用MRR:先通過二級索引的key_part1字段取出滿足條件的key_part1,pk_col order by key_part1.然后通過pk_col去表中取出滿足條件的數據,此時,因為取出的pk_col是亂序的,而表又是pk_col存放數據的,當去表中取數據時,則會產生大量的隨機IO
使用MRR:先通過二級索引的key_part1字段取出滿足條件的key_part1,pk_col order by key_part1.放到緩存中(read_rnd_buffer_size),當對應的緩沖滿了以后,將這部分key值按照pk_col排序,最后再按照排序后的reset去取表中數據,此時pk_col1是順序的,將隨機IO轉化為順序IO,多頁數據記錄可一次性讀入或根據此次的主鍵范圍分次讀入,以減少IO操作,提高查詢效率
Index Condition Pushdown (ICP)是MySQL用索引去表里取數據的一種優化。禁用ICP(MySQL5.6之前),引擎層會利用索引在基表中尋找數據行,然后返回給MySQL Server層,再去為這些數據行進行WHERE后的條件的過濾(回表)。啟用ICP(MySQL5.6之后),如果部分WHERE條件能使用索引中的字段,MySQL會把這部分下推到引擎層。存儲引擎通過使用索引把滿足的行從表中讀取出。ICP減少了引擎層訪問基表的次數和MySQL Server 訪問存儲引擎的次數。總之是 ICP的優化在引擎層就能夠過濾掉大量的數據,減少io次數,提高查詢語句性能