我正在查看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
上的指数大小为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
答案 0 :(得分:2)
您的索引在磁盘上有自己的表(尽管您无法直接'看到'它们)。 db的总大小是表和索引表的大小。
运行
show create table <tablename>;
您可以看到定义的任何索引。想象一下,添加表的总大小以及包含主键中两列的表。添加的那些,将为您提供您所看到的尺寸。
答案 1 :(得分:2)
如果表经常进行插入/删除/更新,您可能需要尝试运行OPTIMIZE TABLE
查询以查看表可以收缩多少。数据文件中可能存在碎片整理和未使用的空格。
phpmyadmin显示的数据大小不符合您的预期。您将在第一次创建表时看到,它不会显示数据用法:0。它将是16KB或32KB或其他东西。插入记录时,大小不会改变。这就是innoDB如何控制表文件的效率。
检查SHOW TABLE STATUS FROM {db_name}
并查看表中每行的Avg_row_length的大小。它不会是19个字节
答案 2 :(得分:2)
磁盘上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
除外)。