![]()
![]()
![]()
![]()
![]()
![]()
這里的表空間呢,指的是獨立表空間,在MySQL中,表空間分為2種,分別是共享表空間和獨立表空間,不過在MySQL 5.6.6及后續版本默認使用的是獨立表空間,
說白了就是一個獨立表空間在磁盤中會單獨對應一個表空間文件,而一個表空間文件存放著MYSQL數據庫中一張表的數據。
在表空間中有很多數據區組,每個數據區組中包含256個數據區,而每個數據區中又包含64個數據頁,因為每個數據頁的大小默認是16KB,所以也就是說一個數據區的大小是1MB。
從磁盤加載數據到MYSQL內存中,其實就是通過磁盤IO的方式,把數據頁中的數據加載到緩沖池Buffer Pool中的緩存頁中,然后通過InnoDB存儲引擎和sql接口,一步步返回給用戶。
那么,在查詢的整個流程中,哪個環節最容易拖后腿呢?答案就是磁盤IO,也就是將磁盤中的數據頁數據讀取到Buffer Pool的緩存頁這個過程。
那么,磁盤IO為什么會拖后腿呢?磁盤IO的過程大概是什么樣子的呢?接下來,就很有必要來看下這一塊內容了。
查詢慢深層次原因揭秘:磁盤IO的過程
先來看下磁盤的物理結構,如下圖:
![]()
磁盤內部的組成部分,主要為主軸、磁盤盤片、讀寫磁頭、傳動軸和傳動手臂,其中數據就是存放在磁盤盤片上的,磁盤盤片被劃分為了無數個小扇區,每個扇區中都有很多半徑不同的環形磁道,不同的磁道中存放著不同的數據。
在實際讀寫數據時,主軸會讓磁盤盤片轉動,然后再通過傳動手臂的伸展,讓讀寫磁頭在磁盤扇區的磁道上讀取和寫入數據,一次磁盤IO花費的時間,主要由尋道時間、旋轉延遲和數據傳輸時間三部分構成,接下來,我們分別來看下這三部分的耗時情況。
1 尋道時間
剛才我們知道了,磁盤盤片表面上被分為了無數小扇區,每個扇區中都有很多半徑不同的磁道,不同的磁道上放著不同的數據。
而尋道時間,指的是將讀寫磁頭移動到正確半徑的磁道上所需要的時間,尋道時間越短,磁盤IO操作越快,目前磁盤的平均尋道時間,一般在3~15ms,主流磁盤一般在5ms以下。
2 旋轉延遲
尋道結束后,還需要讀寫磁頭旋轉到這個磁道的正確位置上才能讀寫數據,而旋轉延遲,指的是從尋道時間結束開始,到讀寫磁頭旋轉到磁道正確位置的這段時間間隔。
但是,我們一般將磁盤旋轉周期值的一半,作為旋轉延遲的近似值;常見的磁盤轉速有5400轉和7200轉,表示每分鐘能轉5400和7200圈。
比如,我們以7200轉舉例,也就是說1秒鐘能轉120圈,磁盤的旋轉周期就是 1/120 秒,所以,旋轉延遲的近似值為 1/120/2 = 4.17ms。
3 數據傳輸時間
傳輸時間,指的是將數據從磁盤盤片讀出或寫入的時間,一般在零點幾毫秒,相對于前兩個時間幾乎可以忽略不計,這樣來看訪問一次磁盤即一次磁盤IO的時間,約等于 5ms + 4.17ms = 9ms。
磁盤的順序讀寫和隨機讀寫
另外,磁盤的數據讀寫,分為隨機讀寫和順序讀寫這兩種,這兩種讀寫數據的方式,與讀寫磁頭讀寫數據的方式有關。
順序讀寫,顧名思義就是讀寫磁頭從磁盤中的一個位置,按照順序依次讀寫磁盤盤片中的數據,速度還是挺快的,比如像MYSQL的redo log日志、binglog日志這些日志信息,比如,順序寫數據時,會相應在一個大日志文件末尾,按照順序添加日志信息。
隨機讀寫時,讀寫磁頭則會在磁盤盤片中,隨機切換到不同半徑的磁道上讀寫數據,頻繁切換磁道的這個過程,是非常耗時的。
所以,隨機讀寫的速度相比于順序讀寫來說,是會慢很多的,而MYSQL從磁盤中讀寫數據,正好是比較耗時的隨機讀寫。
正是因為從MYSQL中查詢數據,往往要發生多次耗時的隨機IO,所以,我們對于一些對查詢效率要求較高的數據,一般都會選擇固態硬盤來存放。
固態硬盤的工作原理,簡單來說就是通過電子的移動來實現數據的讀寫,相比于磁盤這種物理機械的運作方式,速度是快很多的,但是固態硬盤是比較貴的,基于成本考慮,一般公司大部分機器還是會選擇普通機械磁盤的。
磁盤IO到底會有多慢呢?
我們回到剛才,已經知道磁盤IO的工作原理,我們也簡單計算了一下,一次磁盤IO大概是9ms的樣子,看上去還可以,但是9ms已經非常慢了,那到底有多慢呢,我們可以和內存的速度對比一下。
一般一次內存隨機讀取的速度,大概在100ns以內,而 1ms = 1000000ns,可以看到,一次磁盤IO耗時是毫秒級的,而內存是納秒級的。
9ms = 9 * 1000000 ns / 100 ns = 90000,說白了磁盤的速度比內存慢 9萬倍左右,那為什么從內存讀寫數據會那么快呢,簡單來說,內存其實是被CPU控制的,而CPU的時鐘頻率的速度相比于磁盤機械運轉速度,速度可以說是非常快了。
當用戶發起一次查詢請求,一次磁盤IO一般是搞不定的,具體發生磁盤IO的次數,還得要取決于B+樹的高度和當時使用索引的情況。
極端情況下,比如沒用到索引,一次查詢可能會發生100多次磁盤IO,這時,磁盤IO所需的總時間大概是 9ms * 100 = 900ms,也就是0.9秒,這就差不多到秒級別了。
隨著數據的快速增長,比如達到了好幾億的數據量,那需要的磁盤IO次數會大幅增加,那這個時候,一次查詢所需要的時間,就會達到好幾秒。
用戶查詢請求慢的根本原因
現在,我們知道用戶查詢請求慢的根本原因了嗎?
其實說白了,就是隨著數據表中的數據量,變得越來越大,導致磁盤IO發生的次數也相應變多了,如果我們能把磁盤IO的次數降到常數級別,那么查詢速度是非常快的,所以,后邊的優化都是以降低磁盤IO次數為目標。
cpu影響mysql嗎
MySQL是一種開源的關系型數據庫管理系統,而CPU是電腦的“大腦”,兩者密切相關。在MySQL中,對于查詢和處理大量數據,CPU使用率會顯著增加。CPU的性能和配置對MySQL的性能有很大的影響,下面詳細說說。
CPU的性能和核數決定了服務器的處理能力。與MySQL類似的應用程序需要大量的CPU資源,以便快速處理請求。因此,如果CPU存在瓶頸,那么數據庫作為一種I/O密集型應用,將不能得到充分的利用,從而影響MySQL的性能。
與單核CPU相比,具有更多核心的CPU可以提高MySQL的性能。這是因為在多核CPU上,多個線程可以并行執行,從而加快查詢和數據處理的速度。另外,更高的CPU頻率也可以提高性能。
除了CPU的數量和頻率之外,緩存大小對于MySQL性能也很重要。CPU緩存是一個用于存儲近期使用的指令和數據的高速內存系統。盡管CPU緩存的大小通常沒有直接限制MySQL性能的大小,一個合理的緩存值可以提高CPU緩存的命中率,從而縮短了查詢的響應時間。
// 下面是一個在MySQL中執行的簡單查詢語句
SELECT username, email FROM users WHERE age >30;
總之,CPU配置和性能對MySQL性能有很大的影響。為了提高MySQL的性能,可以考慮增加CPU的核數和頻率,同時增加適當的緩存大小,以便加速查詢處理。