MySQL中MRR如何優(yōu)化范圍查詢
一、MRR優(yōu)化概述
MRR,全稱Multi-Range Read Optimization,直譯為多范圍讀取優(yōu)化,是MySQL中一種用于提高索引查詢性能的技術(shù)。MRR通過(guò)減少隨機(jī)磁盤訪問(wèn)次數(shù),將隨機(jī)IO轉(zhuǎn)換為順序IO,從而提高數(shù)據(jù)讀取的效率。它特別適用于包含范圍條件(如BETWEEN、<、>等)的查詢,以及需要通過(guò)輔助索引訪問(wèn)表數(shù)據(jù)的場(chǎng)景。
二、MRR優(yōu)化的背景
在InnoDB中表數(shù)據(jù)是通過(guò)聚集索引組織的。當(dāng)基于輔助索引的范圍查詢時(shí),需要先通過(guò)輔助索引找到對(duì)應(yīng)的主鍵值,再通過(guò)主鍵值回表查詢完整的行數(shù)據(jù)。這種回表會(huì)產(chǎn)生大量的隨機(jī)磁盤I/O,尤其是在處理大表時(shí),隨機(jī)I/O的性能瓶頸尤為明顯。MRR優(yōu)化正是為了解決這一問(wèn)題提出。
三、MRR優(yōu)化的原理
MRR優(yōu)化的核心思想是將多個(gè)范圍查詢中的隨機(jī)磁盤I/O轉(zhuǎn)換為順序磁盤I/O,從而提高查詢性能。
掃描輔助索引并收集主鍵值:
- 當(dāng)執(zhí)行一個(gè)包含范圍條件的查詢時(shí),MySQL優(yōu)化器首先會(huì)掃描輔助索引,找到滿足條件的一系列索引元組。
- 對(duì)于每個(gè)索引元組,MySQL會(huì)收集其對(duì)應(yīng)的主鍵值(rowid)。
對(duì)主鍵值進(jìn)行排序:
- 收集到的主鍵值會(huì)被放入一個(gè)內(nèi)存緩沖區(qū)(read_rnd_buffer)中。
- 當(dāng)緩沖區(qū)滿或查詢結(jié)束時(shí),MySQL會(huì)對(duì)緩沖區(qū)中的主鍵值進(jìn)行排序。排序的目的是為了將隨機(jī)訪問(wèn)轉(zhuǎn)換為順序訪問(wèn)。
順序訪問(wèn)基表:
- 排序后的主鍵值將按照順序被用來(lái)訪問(wèn)基表,檢索出完整的數(shù)據(jù)行。
- 由于主鍵值是有序的,因此訪問(wèn)基表時(shí)產(chǎn)生的磁盤I/O也變?yōu)轫樞騃/O,從而提高了讀取效率。
利用磁盤預(yù)讀和緩存機(jī)制:
- MRR優(yōu)化還充分利用了磁盤的預(yù)讀機(jī)制。當(dāng)請(qǐng)求讀取某一頁(yè)數(shù)據(jù)時(shí),磁盤會(huì)預(yù)測(cè)并提前讀取相鄰的幾頁(yè)數(shù)據(jù)到內(nèi)存中。
- 由于MRR將隨機(jī)訪問(wèn)轉(zhuǎn)換為順序訪問(wèn),磁盤預(yù)讀機(jī)制能夠更好地發(fā)揮作用,減少磁盤尋道時(shí)間和旋轉(zhuǎn)延遲。
- 同時(shí),順序訪問(wèn)也提高了緩存的命中率,因?yàn)檫B續(xù)訪問(wèn)的數(shù)據(jù)頁(yè)更有可能在緩存中找到。
基于成本的決策:
- MySQL優(yōu)化器會(huì)根據(jù)查詢的成本(如I/O成本、CPU成本等)來(lái)決定是否使用MRR優(yōu)化。
- 用戶可以通過(guò)調(diào)整
optimizer_switch
系統(tǒng)變量中的mrr
和mrr_cost_based
標(biāo)志來(lái)控制MRR優(yōu)化的使用。mrr_cost_based
設(shè)置為ON時(shí),優(yōu)化器會(huì)根據(jù)成本來(lái)決定是否使用MRR;設(shè)置為OFF時(shí),則強(qiáng)制使用MRR(但通常不建議這樣做,因?yàn)閮?yōu)化器在大多數(shù)情況下都是正確的)。
四、MRR優(yōu)化的優(yōu)勢(shì)
- 提高查詢性能:通過(guò)減少隨機(jī)磁盤I/O次數(shù)和提高緩存命中率,MRR優(yōu)化能夠顯著提高查詢性能。
- 減少I/O成本:順序I/O比隨機(jī)I/O具有更低的成本,因?yàn)轫樞騃/O可以更有效地利用磁盤帶寬和緩存資源。
- 適用于多種查詢類型:MRR優(yōu)化不僅適用于范圍查詢(如BETWEEN、<、>等),還適用于等值連接(equi-join)等需要回表訪問(wèn)的場(chǎng)景。
五、磁盤預(yù)讀機(jī)制
MRR優(yōu)化充分利用了磁盤預(yù)讀機(jī)制。當(dāng)客戶端請(qǐng)求讀取某一頁(yè)數(shù)據(jù)時(shí),磁盤預(yù)讀功能會(huì)預(yù)測(cè)并提前讀取相鄰的幾頁(yè)數(shù)據(jù)到內(nèi)存緩沖區(qū)中。由于MRR將隨機(jī)訪問(wèn)轉(zhuǎn)換為順序訪問(wèn),磁盤預(yù)讀機(jī)制能夠更好地發(fā)揮作用,減少磁盤尋道時(shí)間和旋轉(zhuǎn)延遲,進(jìn)一步提升讀取效率。
六、局部性原理
局部性原理是MRR優(yōu)化的另一個(gè)理論基礎(chǔ)。時(shí)間局部性表明,如果某個(gè)數(shù)據(jù)項(xiàng)被訪問(wèn),那么在不久的將來(lái)它可能再次被訪問(wèn);空間局部性表明,一旦某個(gè)數(shù)據(jù)項(xiàng)被訪問(wèn),那么其附近的數(shù)據(jù)項(xiàng)也可能很快被訪問(wèn)。MRR通過(guò)順序訪問(wèn)數(shù)據(jù),使得數(shù)據(jù)訪問(wèn)更加符合局部性原理,從而提高了緩存命中率,減少了磁盤訪問(wèn)次數(shù)。
七、使用場(chǎng)景、條件與監(jiān)控
MRR優(yōu)化適用于基于范圍掃描和等值連接的操作中尤為有效。但是,并非所有查詢都能從MRR優(yōu)化中受益。如,當(dāng)查詢完全基于索引元組中的信息(即使用覆蓋索引)時(shí),MRR優(yōu)化就沒(méi)有必要,因?yàn)榇藭r(shí)無(wú)需回表訪問(wèn)基表數(shù)據(jù)。
此外,MySQL默認(rèn)開(kāi)啟MRR優(yōu)化,但是否真正使用MRR由優(yōu)化器決定。優(yōu)化器會(huì)根據(jù)查詢的成本(如IO成本、CPU成本等)來(lái)決定是否采用MRR優(yōu)化。用戶可以通過(guò)調(diào)整optimizer_switch
系統(tǒng)變量中的mrr
和mrr_cost_based
標(biāo)志來(lái)控制MRR優(yōu)化的使用。
1. 配置參數(shù)
- optimizer_switch:包含mrr和mrr_cost_based兩個(gè)選項(xiàng),分別用于控制是否啟用MRR優(yōu)化以及是否基于成本決定是否使用MRR。
- read_rnd_buffer_size:設(shè)置用于給rowid排序的內(nèi)存緩沖區(qū)的大小。這個(gè)參數(shù)的大小會(huì)影響MRR優(yōu)化的效果,需要根據(jù)實(shí)際情況進(jìn)行調(diào)整。
2. 監(jiān)控方法
- 使用EXPLAIN語(yǔ)句查看查詢的執(zhí)行計(jì)劃。如果查詢使用了MRR優(yōu)化,EXPLAIN的輸出會(huì)在Extra列中顯示Using MRR。
- 監(jiān)控查詢的響應(yīng)時(shí)間和I/O開(kāi)銷。通過(guò)比較開(kāi)啟和關(guān)閉MRR優(yōu)化時(shí)的查詢性能,可以評(píng)估MRR優(yōu)化的效果。
八、SQL案例解讀
一個(gè)為orders
的表結(jié)構(gòu)如下:
CREATE TABLE orders ( id INT AUTO_INCREMENT PRIMARY KEY, customer_id INT NOT NULL, order_date DATE NOT NULL, total_amount DECIMAL(10, 2) NOT NULL, INDEX idx_customer_date (customer_id, order_date) ) ENGINE=InnoDB;
表中,customer_id
和order_date
上有一個(gè)聯(lián)合索引idx_customer_date
。想要查詢某個(gè)特定客戶在指定日期范圍內(nèi)的所有訂單,SQL語(yǔ)句:
SELECT * FROM orders WHERE customer_id = 123 AND order_date BETWEEN '2023-01-01' AND '2023-12-31';
掃描輔助索引:
- MySQL首先會(huì)利用輔助索引
idx_customer_date
來(lái)定位滿足customer_id = 123
和order_date BETWEEN '2023-01-01' AND '2023-12-31'
條件的索引元組。 - 這些索引元組包含了
customer_id
、order_date
以及對(duì)應(yīng)的主鍵值(id
)。
- MySQL首先會(huì)利用輔助索引
收集并排序主鍵值:
- MySQL會(huì)收集這些索引元組對(duì)應(yīng)的主鍵值,并將它們放入一個(gè)內(nèi)存緩沖區(qū)(read_rnd_buffer)中。
- 當(dāng)緩沖區(qū)滿或查詢結(jié)束時(shí),MySQL會(huì)對(duì)這些主鍵值進(jìn)行排序。排序的目的是為了后續(xù)的順序訪問(wèn)基表。
順序訪問(wèn)基表:
- 使用排序后的主鍵值,MySQL將順序訪問(wèn)
orders
表的基表部分,檢索出完整的訂單數(shù)據(jù)行。 - 由于主鍵值是有序的,因此訪問(wèn)基表時(shí)產(chǎn)生的磁盤I/O變?yōu)轫樞騃/O,提高了讀取效率。
- 使用排序后的主鍵值,MySQL將順序訪問(wèn)
利用磁盤預(yù)讀和緩存機(jī)制:
- 在順序訪問(wèn)基表的過(guò)程中,磁盤預(yù)讀機(jī)制會(huì)預(yù)測(cè)并提前讀取相鄰的數(shù)據(jù)頁(yè)到內(nèi)存中。
- 這有助于減少磁盤尋道時(shí)間和旋轉(zhuǎn)延遲,并提高緩存命中率。
查詢性能提升:
- 相比沒(méi)有MRR優(yōu)化的情況,使用MRR可以顯著減少隨機(jī)磁盤I/O的次數(shù),從而提高查詢性能。
- 特別是在處理大表時(shí),MRR優(yōu)化的效果更加明顯。
以上就是MySQL中MRR如何優(yōu)化范圍查詢的詳細(xì)內(nèi)容,更多關(guān)于MySQL MRR優(yōu)化范圍查詢的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
設(shè)置MySQLroot賬戶密碼報(bào)錯(cuò)ERROR 1064 (42000): You 
在安裝mysql的時(shí)候,設(shè)置root賬戶密碼出現(xiàn)了ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds..錯(cuò)誤,本文小編給大家介紹了相關(guān)的解決方案,需要的朋友可以參考下2023-12-12MySQL 實(shí)現(xiàn)雙向復(fù)制的方法指南
這篇文章主要介紹了MySQL 實(shí)現(xiàn)雙向復(fù)制的方法指南,本文包括:主機(jī)配置,從機(jī)配置,建立主-從復(fù)制,建立雙向復(fù)制,需要的朋友可以參考下2015-03-03真的了解MySQL中的binlog和redolog區(qū)別
MySQL的binlog和redolog都是用于記錄數(shù)據(jù)庫(kù)操作的日志文件,但是它們有不同的作用和特點(diǎn),今天給大家分享MySQL的binlog和redolog區(qū)別,感興趣的朋友一起看看吧2023-11-11MySQL對(duì)小數(shù)進(jìn)行四舍五入的操作實(shí)現(xiàn)
數(shù)學(xué)函數(shù)是MySQL中常用的一類函數(shù),其主要用于處理數(shù)字,包括整型和浮點(diǎn)數(shù)等等,本文主要介紹了MySQL對(duì)小數(shù)進(jìn)行四舍五入的操作實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08