日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在探索數據庫優化的廣闊領域中,我們不可避免地會遇到一系列獨特的概念和技術。其中之一就是MySQL的多范圍讀取(Multi-Range Read, MRR)。

這種技術為我們提供了在處理大量數據時提高查詢效率的強大手段。它通過改變數據檢索的順序,并利用操作系統緩存進行預讀,從而顯著減少I/O操作數量,提高查詢速度。本文將深入探討MRR的內部工作原理,以及如何在日常數據庫管理中有效地應用這種技術。

什么是MRR

MRR 是優化器將隨機 IO 轉化為順序 IO 以降低查詢過程中 IO 開銷的一種手段。

了解MRR之前,我們先來了解下「回表」。

回表是MySQL在執行查詢時的一個步驟,它通常發生在使用索引進行搜索之后。當MySQL在索引中找到了需要的數據,但這些數據并不完全滿足查詢需求時(比如,索引沒有包含所有需要的列),MySQL就需要回到主表中去獲取完整的行數據,這個過程就被稱為"回表"。

舉例來說,如果查詢語句中有一些列沒有被包含在索引中,那么即使從索引中能查到部分信息,也還需要回到原始表中獲取其他列的信息,這就是所謂的"回表"操作。為了提高查詢效率,我們可以盡量減少回表操作,例如通過使用「覆蓋索引(Covering Index)」。

我們知道二級索引是有回表的過程的,由于二級索引上引用的主鍵值不一定是有序的,因此就有可能造成大量的隨機 IO,如果回表前把主鍵值在內存中給它排一下序,那么在回表的時候就可以用順序 IO 取代原本的隨機 IO。

在沒有MRR的情況下,MySQL會按照索引順序來訪問行數據,而索引順序并不一定與磁盤上的物理存儲順序一致,這就可能產生大量的隨機磁盤I/O。

當啟用MRR后,MySQL會先按照索引掃描記錄,但并不立即去獲取行數據,而是將每個需要訪問的行位置(例如主鍵)保存到一個緩沖區中。

然后,MySQL會根據這些行位置,按照物理存儲的順序(通常也就是主鍵順序)去獲取行數據。這樣就能避免大量的隨機I/O,因為數據現在是按照它們在磁盤上的物理存儲順序被訪問的。

比如,當我執行這個語句時:

select * from t1 where a>=1 and a<=100;

主鍵索引是一棵B+樹,在這棵樹上,每次只能根據一個主鍵id查到一行數據。因此,回表肯定是一行行搜索主鍵索引的,基本流程如圖所示。

如果隨著a的值遞增順序查詢的話,id的值就變成隨機的,那么就會出現隨機訪問,性能相對較差。雖然“按行查”這個機制不能改,但是調整查詢的順序,還是能夠加速的。

因為大多數的數據都是按照主鍵遞增順序插入得到的,所以我們可以認為,如果按照主鍵的遞增順序查詢的話,對磁盤的讀比較接近順序讀,能夠提升讀性能

這,就是MRR優化的設計思路。此時,語句的執行流程變成了這樣:

  1. 根據索引a,定位到滿足條件的記錄,將id值放入read_rnd_buffer中。

  2. 將read_rnd_buffer中的id進行遞增排序。

  3. 排序后的id數組,依次到主鍵id索引中查記錄,并作為結果返回。

這里,read_rnd_buffer的大小是由read_rnd_buffer_size參數控制的。

如果步驟1中,read_rnd_buffer放滿了,就會先執行完步驟2和3,然后清空read_rnd_buffer。之后繼續找索引a的下個記錄,并繼續循環。

下面兩幅圖就是使用了MRR優化后的執行流程和explAIn結果。



從explain結果中,我們可以看到Extra字段多了「Using MRR」,表示的是用上了MRR優化。而且,由于我們在read_rnd_buffer中按照id做了排序,所以最后得到的結果集也是按照主鍵id遞增順序的,也就是與圖1結果集中行的順序相反。

MRR能夠提升性能的核心在于,這條查詢語句在索引a上做的是一個范圍查詢(也就是說,這是一個多值查詢),可以得到足夠多的主鍵id。這樣通過排序以后,再去主鍵索引查數據,才能體現出“順序性”的優勢

簡單來說:MRR 的核心思想就是通過把「隨機磁盤讀」,轉化為「順序磁盤讀」,從而提高了索引查詢的性能

順序讀帶來了兩個好處:

  1. 磁盤和磁頭不再需要來回做機械運動。

  2. 可以充分利用磁盤預讀。

所謂的磁盤預讀,比如說在客戶端請求一頁的數據時,可以把后面幾頁的數據也一起返回,放到數據緩沖池中,這樣如果下次剛好需要下一頁的數據,就不再需要到磁盤讀取。這樣做的理論依據是計算機科學中著名的局部性原理:當一個數據被用到時,其附近的數據也通常會馬上被使用

MRR 在本質上是一種用「空間換時間」的做法

MySQL 不可能給你無限的內存來進行排序,這塊內存的大小就由參數read_rnd_buffer_size來控制,如果read_rnd_buffer滿了,就會先把滿了的 rowid 排好序去磁盤讀取,接著清空,然后再往里面繼續放 rowid,直到 read_rnd_buffer 又達到 read_rnd_buffe 配置的上限,如此循環。

MRR如何使用

MRR相關參數如下:

//如果你不打開,是一定不會用到 MRR 的。
set optimizer_switch='mrr=on';
set optimizer_switch ='mrr_cost_based=off';
set read_rnd_buffer_size = 32 * 1024 * 1024;

mrr_cost_based: on/off,則是用來告訴優化器,要不要基于使用 MRR 的成本,考慮使用 MRR 是否值得(cost-based choice),來決定具體的 SQL 語句里要不要使用 MRR。

很明顯,對于只返回一行數據的查詢,是沒有必要 MRR 的,而如果你把 mrr_cost_based 設為 off,那優化器就會通通使用 MRR,這在有些情況下是很 stupid 的,所以建議這個配置還是設為 on,畢竟優化器在絕大多數情況下都是正確的。

通過本文我們可以了解到,MySQL的多范圍讀取(MRR)優化提供了一個高效的方式來處理和加速查詢性能。特別是在處理大量數據、聯接操作或者需要處理大量行的復雜查詢時,MRR都會展現出其強大的優勢。

然而,我們也要注意到,不是所有情況下啟用MRR都會提升性能,一些具體的場景可能會產生額外的磁盤I/O開銷。因此,理解其工作原理并合適地運用在恰當的場景,才是有效使用這個優化策略的關鍵。

分享到:
標簽:MySQL
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定