[英]Why is my table size more than 4x larger than expected? (rows*bytes/row)
我在看MySQL中一個簡單的表,它有4列,大小如下,
unsigned bigint (8 bytes)
unsigned bigint (8 bytes)
unsigned smallint (2 bytes)
unsigned tinyint (1 byte)
所以我希望19字節/行。
此表中有1,654,150行,因此數據大小應為31,428,850字節(或大約30兆字節)。
但我可以通過phpMyAdmin看到數據占用136.3 MiB(不包括bigint 1, smallint, tinyint
上的索引大小bigint 1, smallint, tinyint
為79 MiB)。
存儲引擎是InnoDB,主鍵是bigint 1, bigint 2
(用戶ID和唯一的項ID)。
編輯:根據注釋中的請求,這是SHOW CREATE TABLE storage
CREATE TABLE `storage` (
`fbid` bigint(20) unsigned NOT NULL,
`unique_id` bigint(20) unsigned NOT NULL,
`collection_id` smallint(5) unsigned NOT NULL,
`egg_id` tinyint(3) unsigned NOT NULL,
PRIMARY KEY (`fbid`,`unique_id`),
KEY `fbid` (`fbid`,`collection_id`,`egg_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
您的索引在磁盤上有自己的表(盡管您不能直接'看到'它們)。 db的總大小是表和索引表的大小。
跑
show create table <tablename>;
您可以看到定義的任何索引。 想象一下,添加表的總大小以及包含主鍵中兩列的表。 添加的那些,將為您提供您所看到的尺寸。
如果表經常進行插入/刪除/更新,您可能希望嘗試運行OPTIMIZE TABLE
查詢以查看表可以收縮多少。 數據文件中可能存在碎片整理和未使用的空格。
phpmyadmin顯示的數據大小將不符合您的預期。 您將在第一次創建表時看到,它不會顯示數據用法:0。它將是16KB或32KB或其他東西。 插入記錄時,大小不會改變。 這就是innoDB如何控制表文件的效率。
檢查SHOW TABLE STATUS FROM {db_name}
並查看表中每行的Avg_row_length的大小。 它也不會是19個字節
磁盤上InnoDB的數據大小通常是您計算的2-3倍。 這是因為
有一點可以幫助:幾乎沒有應用程序需要BIGINT
(8字節)用於ID。 考慮INT UNSIGNED
(4字節,4B限制)或MEDIUMINT UNSIGNED
(3字節,16M限制)等。您有2個Bigint,但它們有4個副本 - 輔助密鑰隱含地包括PK列。
PRIMARY KEY
與數據一起存儲,因此它產生的開銷非常小。 輔助密鑰(實際上是4列)是具有類似開銷的BTree。
即使在MyISAM中,也存在開銷:
NULLable
列1個字節(在您的情況下沒有) DELETEd
或UPDATEd
。 (由於FIXED
記錄大小,在您的情況下更新不會有問題。) PRIMARY KEY
就像任何其他索引一樣 (因為你沒有VARCHAR
或TEXT
,所以我不需要討論`CHARACTER SET問題。)
在InnoDB中, SHOW TABLE STATUS
在行數估計中經常偏差2倍。 Avg_row_length計算為Data_length / Rows,因此它通常是關閉的。
我不推薦InnoDB表的OPTIMIZE TABLE
; 它幾乎總是不值得努力。
在做ALTER TABLE .. ADD INDEX ..
,舊版本的MySQL會重建整個表和索引。 這樣做可以獲得OPTIMIZE
的效果。 (數據大小增加不太可能,但並非不可能。)較新版本僅添加新索引。 你正在運行什么版本?
每個INDEX
是一個單獨的BTree(InnoDB中的PK除外)(除了FULLTEXT
和SPATIAL
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.