自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入淺出MySQL MRR(Multi-Range Read)

數(shù)據(jù)庫 MySQL
本文將深入探討MRR的內(nèi)部工作原理,以及如何在日常數(shù)據(jù)庫管理中有效地應用這種技術。

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

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

什么是MRR

MRR 是優(yōu)化器將隨機 IO 轉(zhuǎn)化為順序 IO 以降低查詢過程中 IO 開銷的一種手段。

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

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

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

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

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

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

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

比如,當我執(zhí)行這個語句時:

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

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

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

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

這,就是MRR優(yōu)化的設計思路。此時,語句的執(zhí)行流程變成了這樣:

  • 根據(jù)索引a,定位到滿足條件的記錄,將id值放入read_rnd_buffer中。
  • 將read_rnd_buffer中的id進行遞增排序。
  • 排序后的id數(shù)組,依次到主鍵id索引中查記錄,并作為結果返回。

這里,read_rnd_buffer的大小是由read_rnd_buffer_size參數(shù)控制的。

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

下面兩幅圖就是使用了MRR優(yōu)化后的執(zhí)行流程和explain結果。

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

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

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

順序讀帶來了兩個好處:

  • 磁盤和磁頭不再需要來回做機械運動。
  • 可以充分利用磁盤預讀。

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

MRR 在本質(zhì)上是一種用「空間換時間」的做法。

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

MRR如何使用

MRR相關參數(shù)如下:

//如果你不打開,是一定不會用到 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,則是用來告訴優(yōu)化器,要不要基于使用 MRR 的成本,考慮使用 MRR 是否值得(cost-based choice),來決定具體的 SQL 語句里要不要使用 MRR。

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

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

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

責任編輯:趙寧寧 來源: Java隨想錄
相關推薦

2021-07-19 11:54:15

MySQL優(yōu)先隊列

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2009-03-16 13:44:29

雙向復制實例MySQL

2023-02-14 08:00:00

MySQL索引查詢

2017-07-02 18:04:53

塊加密算法AES算法

2019-01-07 15:29:07

HadoopYarn架構調(diào)度器

2021-07-20 15:20:02

FlatBuffers阿里云Java

2012-05-21 10:06:26

FrameworkCocoa

2022-09-26 09:01:15

語言數(shù)據(jù)JavaScript

2018-03-15 09:13:43

MySQL存儲引擎

2019-08-22 10:57:42

MySQL數(shù)據(jù)索引

2009-11-30 16:46:29

學習Linux

2022-01-11 07:52:22

CSS 技巧代碼重構

2019-11-11 14:51:19

Java數(shù)據(jù)結構Properties

2019-12-04 10:13:58

Kubernetes存儲Docker

2022-11-09 08:06:15

GreatSQLMGR模式

2021-04-27 08:54:43

ConcurrentH數(shù)據(jù)結構JDK8

2009-11-18 13:30:37

Oracle Sequ

2012-02-21 13:55:45

JavaScript
點贊
收藏

51CTO技術棧公眾號