MySQL單表存多大的資料量比較合適

码奇码發表於2024-10-06

前言

經常使用MySQL資料庫的小夥伴都知道,當單表資料量達到一定的規模以後,查詢效能就會顯著降低。因此,當單表資料量過大時,我們往往要考慮進行分庫分表。那麼如何計算單表儲存多大的資料量合適?當單表資料達到多大的規模時,我們才要進行分庫分表呢?

MySQL儲存方式

首先我們要先了解一下MySQL儲存資料的方式,以下都是針對InnoDB引擎來講解的。

資料頁

為了提高資料查詢效率,MySQL採用了資料頁的方式進行資料儲存,一個資料頁的大小是16KB,可以透過以下語句查詢。

mysql> SHOW GLOBAL STATUS LIKE 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.00 sec)

根據結構示意圖,我們可以看到,在這16KB的資料裡,除了包括我們要記錄的資料,還包含頁頭和頁尾的開銷(大約200位元組)。因此,一個資料頁中的有效資料空間大概為16184位元組。

索引結構

InnoDB引擎的索引結構是B+樹,只有葉子節點會儲存記錄的資料,非葉子節點只存索引。

資料量計算

通常來說,三層B+樹的索引結構可以達到一個較好的檢索效能,只需三次磁碟IO即可完成資料查詢。因此,我們以此為例進行計算。

根節點計算

我們假設資料表的主鍵是一個bigint型別的欄位,bigint型別的長度是8Byte。而根節點除了要儲存主鍵欄位資料,還有儲存下一層索引資料頁的地址,大小為6Byte。
可以算出一條資料的索引所佔空間為8+6=14Byte,進而可以算出根節點可以儲存16184/14=1156個指標。

第二層節點計算

第二層的每個節點的指標數量和根節點一樣,都是1156個指標,節點數量和根節點的指標數量一致。因此可以得出,第二層的指標數量為1156*1156=1336336。

葉子節點計算

我們假設一行資料有100個位元組,那麼一個葉子節點可以儲存16184/100≈161條資料。與第二層的指標數量相乘以後,可以得出總資料量為1336336*161=215150096條資料,大約2億多條。

總結

透過以上的分析,我們可以發現,關於單表的資料量條數限制並沒有一個統一的答案。單表可容納多少資料量,這與表的主鍵以及資料行長度息息相關,需要具體情況具體分析。
另外,在阿里的開發規範中,關於資料庫的建表規約,有一條這樣的建議:

【推薦】單錶行數超過 500 萬行或者單表容量超過 2GB,才推薦進行分庫分表。
說明:如果預計三年後的資料量根本達不到這個級別,請不要在建立表時就分庫分表。

這個資料規模要比我們計算出來的小很多,可能由以下幾個方面的原因導致:
1、實際業務中的表欄位長度一般不止100個位元組,主鍵索引結構也可能更加複雜,導致單個資料頁可以儲存的資料量大大降低;
2、磁碟IO效能的限制,當時機械硬碟還是主流,對資料量限制較為嚴格;
3、資料備份和恢復的難度,資料量過大會導致資料備份和恢復的難度大大提高。

相關文章