成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL 的 MRR 到底是什么?

數據庫 MySQL
MRR,全稱「Multi-Range Read Optimization」。 簡單說:MRR 通過把「隨機磁盤讀」,轉化為「順序磁盤讀」,從而提高了索引查詢的性能。

[[317527]]

 MRR,全稱「Multi-Range Read Optimization」。

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

至于:

  • 為什么要把隨機讀轉化為順序讀?
  • 怎么轉化的?
  • 為什么順序讀就能提升讀取性能?

咱們開始吧。

磁盤:苦逼的底層勞動人民

執行一個范圍查詢:

 

  1. mysql > explain select * from stu where age between 10 and 20; 
  2. +----+-------------+-------+-------+------+---------+------+------+-----------------------+ 
  3. | id | select_type | table | type  | key  | key_len | ref  | rows | Extra                 | 
  4. +----+-------------+-------+-------+----------------+------+------+-----------------------+ 
  5. |  1 | SIMPLE      |  stu  | range | age  | 5       | NULL |  960 | Using index condition | 
  6. +----+-------------+-------+-------+----------------+------+------+------------- 

當這個 sql 被執行時,MySQL 會按照下圖的方式,去磁盤讀取數據(假設數據不在數據緩沖池里):

 

 

 

 

圖中紅色線就是整個的查詢過程,藍色線則是磁盤的運動路線。

這張圖是按照 Myisam 的索引結構畫的,不過對于 Innodb 也同樣適用。

對于 Myisam,左邊就是字段 age 的二級索引,右邊是存儲完整行數據的地方。

先到左邊的二級索引找,找到第一條符合條件的記錄(實際上每個節點是一個頁,一個頁可以有很多條記錄,這里我們假設每個頁只有一條),接著到右邊去讀取這條數據的完整記錄。

讀取完后,回到左邊,繼續找下一條符合條件的記錄,找到后,再到右邊讀取,這時發現這條數據跟上一條數據,在物理存儲位置上,離的賊遠!

咋辦,沒辦法,只能讓磁盤和磁頭一起做機械運動,去給你讀取這條數據。

第三條、第四條,都是一樣,每次讀取數據,磁盤和磁頭都得跑好遠一段路。

磁盤的簡化結構可以看成這樣:

 

 

 

 

 

 

 

 

可以想象一下,為了執行你這條 sql 語句,磁盤要不停的旋轉,磁頭要不停的移動,這些機械運動,都是很費時的。

10,000 RPM(Revolutions Per Minute,即轉每分) 的機械硬盤,每秒大概可以執行 167 次磁盤讀取,所以在極端情況下,MySQL 每秒只能給你返回 167 條數據,這還不算上 CPU 排隊時間。

上面講的都是機械硬盤,SSD 的土豪,請隨意 - -

對于 Innodb,也是一樣的。 Innodb 是聚簇索引(cluster index),所以只需要把右邊也換成一顆葉子節點帶有完整數據的 B+ tree 就可以了。

順序讀:一場狂風暴雨般的革命

到這里你知道了磁盤隨機訪問是多么奢侈的事了,所以,很明顯,要把隨機訪問轉化成順序訪問:

 

  1. mysql > set optimizer_switch='mrr=on'
  2. Query OK, 0 rows affected (0.06 sec) 
  3.  
  4. mysql > explain select * from stu where age between 10 and 20; 
  5. +----+-------------+-------+-------+------+---------+------+------+----------------+ 
  6. | id | select_type | table | type  | key  | key_len | ref  | rows | Extra          | 
  7. +----+-------------+-------+-------+------+---------+------+------+----------------+ 
  8. |  1 | SIMPLE      | tbl   | range | age  |    5    | NULL |  960 | ...; Using MRR | 
  9. +----+-------------+-------+-------+------+---------+------+------+----------------+ 

我們開啟了 MRR,重新執行 sql 語句,發現 Extra 里多了一個「Using MRR」。

這下 MySQL 的查詢過程會變成這樣:

 

 

 

 

對于 Myisam,在去磁盤獲取完整數據之前,會先按照 rowid 排好序,再去順序的讀取磁盤。

對于 Innodb,則會按照聚簇索引鍵值排好序,再順序的讀取聚簇索引。

順序讀帶來了幾個好處:

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

2、可以充分利用磁盤預讀

比如在客戶端請求一頁的數據時,可以把后面幾頁的數據也一起返回,放到數據緩沖池中,這樣如果下次剛好需要下一頁的數據,就不再需要到磁盤讀取。這樣做的理論依據是計算機科學中著名的局部性原理:

當一個數據被用到時,其附近的數據也通常會馬上被使用。

3、在一次查詢中,每一頁的數據只會從磁盤讀取一次

MySQL 從磁盤讀取頁的數據后,會把數據放到數據緩沖池,下次如果還用到這個頁,就不需要去磁盤讀取,直接從內存讀。

但是如果不排序,可能你在讀取了第 1 頁的數據后,會去讀取第2、3、4頁數據,接著你又要去讀取第 1 頁的數據,這時你發現第 1 頁的數據,已經從緩存中被剔除了,于是又得再去磁盤讀取第 1 頁的數據。

而轉化為順序讀后,你會連續的使用第 1 頁的數據,這時候按照 MySQL 的緩存剔除機制,這一頁的緩存是不會失效的,直到你利用完這一頁的數據,由于是順序讀,在這次查詢的余下過程中,你確信不會再用到這一頁的數據,可以和這一頁數據說告辭了。

順序讀就是通過這三個方面,最大的優化了索引的讀取。

別忘了,索引本身就是為了減少磁盤 IO,加快查詢,而 MRR,則是把索引減少磁盤 IO 的作用,進一步放大。

一些關于這場革命的配置

和 MRR 相關的配置有兩個:

  • mrr: on/off
  • mrr_cost_based: on/off

第一個就是上面演示時用到的,用來打開 MRR 的開關:

 

  1. mysql > set optimizer_switch='mrr=on'

如果你不打開,是一定不會用到 MRR 的。

另一個,則是用來告訴優化器,要不要基于使用 MRR 的成本,考慮使用 MRR 是否值得(cost-based choice),來決定具體的 sql 語句里要不要使用 MRR。

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

另外還有一個配置 read_rnd_buffer_size ,是用來設置用于給 rowid 排序的內存的大小。

顯然,MRR 在本質上是一種用空間換時間的算法。MySQL 不可能給你無限的內存來進行排序,如果 read_rnd_buffer 滿了,就會先把滿了的 rowid 排好序去磁盤讀取,接著清空,然后再往里面繼續放 rowid,直到 read_rnd_buffer 又達到 read_rnd_buffe 配置的上限,如此循環。

尾聲

你也看出來了,MRR 跟索引有很大的關系。

索引是 MySQL 對查詢做的一個優化,把原本雜亂無章的數據,用有序的結構組織起來,讓全表掃描變成有章可循的查詢。

而我們講的 MRR,則是 MySQL 對基于索引的查詢做的一個的優化,可以說是對優化的優化了。

要優化 MySQL 的查詢,就得先知道 MySQL 的查詢過程;而要優化索引的查詢,則要知道 MySQL 索引的原理。

就像之前在「如何學習 MySQL」里說的,要優化一項技術、學會調優,首先得先弄懂它的原理,這兩者是不同的 Level。

以上(此處應該有點贊)。

責任編輯:武曉燕 來源: 柳樹的絮叨叨
相關推薦

2022-10-08 00:00:00

Spring數據庫項目

2020-10-14 06:22:14

UWB技術感知

2020-09-27 06:53:57

MavenCDNwrapper

2020-09-22 08:22:28

快充

2010-11-01 01:25:36

Windows NT

2011-04-27 09:30:48

企業架構

2024-05-13 12:44:00

InnodbMySQL行級鎖

2023-10-11 08:29:54

volatileJava原子性

2009-06-09 22:11:44

JavaScriptObject

2021-09-01 23:29:37

Golang語言gRPC

2021-01-21 21:24:34

DevOps開發工具

2021-02-05 10:03:31

區塊鏈技術智能

2023-07-12 15:32:49

人工智能AI

2021-07-07 05:07:15

JDKIterator迭代器

2024-02-04 00:01:00

云原生技術容器

2013-06-09 09:47:31

.NetPDBPDB文件

2021-09-03 09:12:09

Linux中斷軟件

2019-10-30 10:13:15

區塊鏈技術支付寶

2010-04-22 14:14:29

Live-USB

2020-08-04 14:20:20

數據湖Hadoop數據倉庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99自拍视频 | 午夜三级视频 | 日韩伦理一区二区三区 | 成人小视频在线观看 | 中文字幕一区二区三区乱码在线 | 国产999精品久久久久久 | 一色一黄视频 | jav成人av免费播放 | 欧美九九九 | 日韩精品免费看 | 毛色毛片免费看 | 97精品超碰一区二区三区 | 在线观看免费av网 | 婷婷久久综合 | 亚洲精品久久久久中文字幕欢迎你 | 日本中文字幕一区 | 亚洲一区二区视频在线播放 | 国产99久久精品 | 一级少妇女片 | 国产美女自拍视频 | 欧美v在线 | av在线免费网站 | 国产伦精品一区二区三区精品视频 | 不卡的av在线 | 精品视频一区二区 | 日本超碰 | 亚洲有码转帖 | 欧美日韩精品中文字幕 | 亚洲人人舔人人 | 精品国产一区二区三区久久 | 天堂一区 | 超碰精品在线观看 | 日本在线免费看最新的电影 | 欧美久久一区二区 | 日韩福利片 | 羞羞羞视频 | 国产成人精品久久二区二区91 | 久久久久一区 | 97国产精品视频人人做人人爱 | 国产亚洲精品久久19p | 国产精品18久久久久久白浆动漫 |