首先說明一下:
MySQL并沒有硬性規(guī)定只能支持到2000萬左右的數(shù)據(jù)量。
其實(shí),MySQL能夠處理的數(shù)據(jù)量遠(yuǎn)遠(yuǎn)超過這個數(shù)字。無論是開源社區(qū)版還是商業(yè)版,
MySQL在適當(dāng)?shù)挠布团渲孟?,都能夠支持非常大的?shù)據(jù)集。
通常所說的“MySQL只能支持2000萬左右的數(shù)據(jù)量”,是在談?wù)摼唧w的一些使用場景時大概的估算值,
受到某些配置、硬件資源或設(shè)計(jì)上的限制。在這些情況下,MySQL的性能可能會遇到瓶頸。
這些瓶頸可能來自于硬件限制、表結(jié)構(gòu)設(shè)計(jì)、配置不當(dāng)、查詢優(yōu)化、并發(fā)處理等。
2000萬的數(shù)據(jù)量是如何估算的?
這里就不得提及數(shù)據(jù)庫索引的構(gòu)建,以及InnoDB存儲引擎的結(jié)構(gòu)和它是如何存儲數(shù)據(jù)與索引的了。
索引的構(gòu)建
索引是數(shù)據(jù)庫中的一個數(shù)據(jù)結(jié)構(gòu),可以幫助快速定位到表中特定行的記錄,就像書的目錄能幫助你快速找到某個主題的章節(jié)一樣。在MySQL的InnoDB存儲引擎中,索引通常是使用B-Tree(具體來說是B+Tree)數(shù)據(jù)結(jié)構(gòu)來構(gòu)建的。
構(gòu)建索引的過程如下:
- 選擇索引列:通常,你會為表中的主鍵、經(jīng)常用于查詢條件(WHERE子句)的列、經(jīng)常參與連接操作的列(JOIN條件)或者是經(jīng)常需要排序和分組的列(ORDER BY、GROUP BY子句)創(chuàng)建索引。
- 確定索引類型:可以是單列索引,也可以是多列組合索引。組合索引考慮列的順序,這會影響其效率。
-
創(chuàng)建索引:使用SQL語句
CREATE INDEX
或者在創(chuàng)建表的時候直接定義。 - InnoDB處理索引:InnoDB存儲引擎會在后臺創(chuàng)建并維護(hù)相應(yīng)的B+Tree結(jié)構(gòu),每個索引都會對應(yīng)一棵B+Tree。
InnoDB的結(jié)構(gòu)
InnoDB是MySQL的默認(rèn)存儲引擎,它支持事務(wù)、行級鎖定和外鍵。它的主要結(jié)構(gòu)包括:
- 表空間(Tablespace):InnoDB使用表空間來存儲數(shù)據(jù)和索引。表空間可以是單個文件(file-per-table模式)也可以是共享的(如ibdata文件)。
- 數(shù)據(jù)頁(Data Page):InnoDB將數(shù)據(jù)存儲在頁中,通常大小為16KB。數(shù)據(jù)頁按行記錄組織。
- B+Tree索引結(jié)構(gòu):這種索引結(jié)構(gòu)有幾個特點(diǎn)——平衡的樹形結(jié)構(gòu),所有的葉子節(jié)點(diǎn)都在同一層,葉子節(jié)點(diǎn)之間是雙向鏈表,葉子節(jié)點(diǎn)包含所有數(shù)據(jù)信息。
InnoDB如何存儲數(shù)據(jù)與索引
在InnoDB中,表數(shù)據(jù)本身就是按照主鍵順序存儲的,這種結(jié)構(gòu)被稱為聚簇索引(Clustered Index)。每張表的聚簇索引是其主鍵索引,意味著表數(shù)據(jù)都存放在主鍵索引的B+Tree結(jié)構(gòu)中的葉子節(jié)點(diǎn)上。如果表沒有顯式的主鍵,InnoDB會選擇一個唯一索引代替;如果沒有唯一索引,InnoDB會自動生成一個隱藏的row ID來作為主鍵。
對于非主鍵索引(也稱為二級索引或輔助索引),葉子節(jié)點(diǎn)不直接存儲行數(shù)據(jù),而是存儲相應(yīng)行的主鍵值。當(dāng)通過輔助索引查找數(shù)據(jù)時,會先在輔助索引的B+Tree中找到主鍵,然后再通過主鍵在聚簇索引中檢索實(shí)際的行數(shù)據(jù)。
索引與2000萬數(shù)據(jù)的關(guān)系
索引可以顯著提高查詢效率,尤其是在數(shù)據(jù)量大的表中。
但同時,索引也占用磁盤空間,并且在插入、更新和刪除操作時需要額外的維護(hù)成本,因?yàn)椴粌H是數(shù)據(jù)本身,索引也需要相應(yīng)地更新。
在數(shù)據(jù)庫設(shè)計(jì)中,特別是當(dāng)涉及到大量數(shù)據(jù)的時候,考慮B+樹索引的層數(shù)是非常重要的。主鍵列被廣泛使用bigint類型,這主要是因?yàn)閎igint類型的整數(shù)范圍很大(從-263到263-1),
能夠支持極大量的數(shù)據(jù)行,這對于有大量數(shù)據(jù)的系統(tǒng)來說非常有用。
B+樹索引層數(shù)的影響
B+樹索引的層數(shù)決定了查詢需要多少次磁盤I/O操作才能找到指定的數(shù)據(jù)。
理論上,B+樹的每增加一層,就能夠索引更多的數(shù)據(jù),但同時也意味著訪問數(shù)據(jù)時需要更多的磁盤訪問次數(shù)。
因此,數(shù)據(jù)庫系統(tǒng)通常盡可能地減少這些層數(shù)。
如何估算B+樹索引的層數(shù)
假設(shè)我們使用的是InnoDB存儲引擎,一個頁(Page)默認(rèn)是16KB大小,而一個bigint類型的索引大約需要8字節(jié)(實(shí)際上可能更多一點(diǎn),因?yàn)檫€包括了頁的指針,假設(shè)為14字節(jié))。我們可以大概估算一下:
- 首先算每個葉子結(jié)點(diǎn)能夠存儲的數(shù)據(jù)量(假設(shè)每條數(shù)據(jù)1k,那么每個page能存儲16條,非葉子節(jié)點(diǎn)的上一層節(jié)點(diǎn)數(shù) = 數(shù)據(jù)量 / 16)
- 然后,假設(shè)每個非葉子節(jié)點(diǎn)存儲的節(jié)點(diǎn)數(shù)量是 x,那么第一層就是 x = 16384 / 14;第二層就是,x的平方,三層就是x的三次方,以此類推
- 計(jì)算值與非葉子節(jié)點(diǎn)的上一層節(jié)點(diǎn)數(shù)比較即可得到層數(shù)
為何MySQL建議樹的層數(shù)不超過三層?
B+樹的層數(shù)建議限制在3層以內(nèi),主要是基于性能的考慮。當(dāng)B+樹的層數(shù)增加時,每次查詢數(shù)據(jù)所需的磁盤I/O次數(shù)也會增加,因?yàn)槊恳粚佣伎赡苌婕暗揭淮未疟PI/O(盡管數(shù)據(jù)庫的緩存機(jī)制可以減少這種情況發(fā)生的頻率)。磁盤I/O通常比CPU計(jì)算和內(nèi)存訪問要慢得多,因此,為了維持?jǐn)?shù)據(jù)庫查詢的高性能,建議盡量減少層數(shù)。
現(xiàn)在我們來估算一下三層B+樹能存放多少索引條目。以InnoDB存儲引擎為例,它的默認(rèn)頁大小是16KB(16384字節(jié))。
我們假設(shè)現(xiàn)在數(shù)據(jù)庫中的每一條數(shù)據(jù)為1k,每個索引條目大小為14字節(jié)(如果包含事務(wù)ID和回滾指針的話),
那么每個數(shù)據(jù)頁假設(shè)存儲16條數(shù)據(jù)。
下面是計(jì)算過程:
- 第一層:每個頁可以存儲的索引條目數(shù)為 16384 / 14 ≈ 1170 ,第一層有1170個葉子節(jié)點(diǎn)。
- 第二層:如果第二層也是完全填滿的,那么它可以索引 1170 * 1170 ≈ 1368900, 第一層有1368900個葉子節(jié)點(diǎn)。
- 第三層(葉子節(jié)點(diǎn)):同理,第三層可以索引 1368900 * 16 ≈ 21902400 條數(shù)據(jù)。
這里是以bigint類型舉例,當(dāng)使用的類型不同時,存儲的索引量不同,而且還與每行的數(shù)據(jù)大小有關(guān)。
總結(jié)
因此“2000萬的數(shù)據(jù)量是如何估算的”這個說法是錯誤的,我們要根據(jù)自己的業(yè)務(wù)場景,具體情況具體分析。
可以使用預(yù)估的方式,計(jì)算在B+樹的層數(shù)為3時,最大的數(shù)據(jù)量,當(dāng)數(shù)據(jù)量遠(yuǎn)大于這個數(shù)值時,可以通過增加內(nèi)存的方式,或者分庫分表解決查詢慢的情況。
最后說一句(求關(guān)注,求贊,別白嫖我)
最近無意間獲得一份阿里大佬寫的刷題筆記和面經(jīng),一下子打通了我的任督二脈,進(jìn)大廠原來沒那么難。
這是大佬寫的, 7701頁的阿里大佬寫的刷題筆記,讓我offer拿到手軟
求一鍵三連:點(diǎn)贊、分享、收藏文章來源:http://www.zghlxwxcb.cn/news/detail-858032.html
點(diǎn)贊對我真的非常重要!在線求贊,加個關(guān)注我會非常感激!@小鄭說編程文章來源地址http://www.zghlxwxcb.cn/news/detail-858032.html
到了這里,關(guān)于Mysql為什么只能支持2000w左右的數(shù)據(jù)量?的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!