我正在学习如何通过为列重新选择正确的数据类型来优化我的数据库,我想知道如果我选择了,我将节省多少大小 MEDIUMINT
(3字节)而不是 INT
(4字节)
afaik-如果我错了,请纠正我-我需要数据库大小尽可能小,以适应ram,以减少硬桌面请求。数据库的大小由表大小+索引大小组成
给我一个 INT
列,如果我将列的数据类型从 INT
至 MEDIUMINT
在
表数据大小?
索引大小?
注意:我知道mysql不会减少磁盘上的实际大小,除非我优化表
编辑:我的情况是,我将完成我生命中第一个严肃的系统-这是一个erp系统,我计划在阿拉伯地区的市场销售-。计划1、2、3、4数据库的容量应该分别约为2gb、4gb、10gb和40gb,因此,如果我可以在不牺牲性能/功能的情况下减小每个数据库的大小,为什么不呢?如果我能让一台32gb内存的机器为4个客户机而不是2个客户机服务,为什么不呢?
3条答案
按热度按时间csga3l581#
只是使用
INT
除非你有一个具体的,可测量的问题。在一个连最节俭的智能手机都有10亿字节用于存储的时代,如果你为每一个字节而烦恼,你只会把事情弄得一团糟。我需要的数据库大小尽可能小,以适应内存,以减少硬桌面请求。
不,你没有。您需要数据库易于使用和充分执行。在ssd支持的数据库时代,只有在大规模操作之前,i/o才是一个问题,如果这一天到来,那么您可以进行测量并了解您遇到的具体问题。
从你的
INT
字段不太可能做得更好,因为三字节整数值不是cpu可以直接处理的。这些数据将被转换成四个字节,并正确对齐,以便理解,与读取一个普通的32位整数相比,这是一个混乱的过程。记住,mysql来自一个高端服务器拥有64MB内存和9G硬盘的时代。那时候你确实需要把字节数剃掉,因为你只有一小部分字节。
现在我们还有其他的问题,比如你会不会像slashdot那样不小心耗尽你的24位整数空间,因为正是你打算在这里做的那种“优化”。
小心。当你有具体的理由去优化时,不要仅仅因为你认为你需要。避免过早的优化是开发过程中经常遇到的困难,但是如果你有纪律,你可以避免它。
kb5ga3dv2#
(我不同意其他一些回答/评论。我会尽量回答所有的问题,并解决所有我不同意的问题。)
MEDIUMINT
是3字节,每行节省1字节INT
.TINYINT
是1字节,每行节省3字节INT
.在这两种情况下,在任何情况下,每次出现都会保存1或3个字节
INDEX
除了PRIMARY KEY
.如果ram中的数据+索引可能比空间多,那么收缩数据类型是明智的,但要保守。
使用
MEDIUMINT UNSIGNED
(等)如果值是非负的,例如AUTO_INCREMENT
. 这给了你一个16米的极限,而不是8米(是的,是的,这是一个小小的进步。)当心“烧”
AUTO_INCREMENT
身份证--INSERT IGNORE
(和其他几个命令)将在检查是否使用前分配下一个auto\u inc。即使数据+索引超过ram大小(实际上
innodb_buffer_pool_size
),它可能不会减慢到磁盘速度--这取决于数据的访问模式。小心uuid,它们非常随机。在无法缓存整个索引时使用uuid是致命的。缓冲池是一个缓存(我看到1tb的数据集运行速度足够快,只有32gb的ram和一个旋转的磁盘。)使用
ALTER TABLE
更改数据类型可能(我不确定)会重建表,从而执行OPTIMIZE TABLE
.如果表是用
innodb_file_per_table = OFF
你把它转过来ON
在做这个之前ALTER
,你得到一个单独的表文件,但是ibdata1
不会收缩(反而会有更多的可用空间)。3字节数字的对齐——不是问题。2的幂与此无关。mysql假设所有列的边界都很差,大小也很差。所有数字都转换为通用格式(64位数字)以进行操作。这种转换是总时间中不重要的部分——获取行(即使缓存)是最昂贵的部分。
当i/o绑定时,缩小数据类型会导致每个块有更多的行,从而导致更少的磁盘命中(uuid情况除外)。当i/o绑定时,命中磁盘是最大的性能开销。
“空值不占用空间”-https://dev.mysql.com/doc/internals/en/innodb-field-contents.html . 所以,同样,i/o更少。但是,当心,如果这导致额外的检查
NULL
在一个SELECT
,这可能导致表扫描而不是使用索引。打10米远比只打几排差。至于32gb可以容纳多少个客户机——可能是6个或更多。记住,缓冲池是一个缓存;数据和索引是逐块缓存的(innodb块为16kb。)
还有一件事。。。在投入生产之前压缩数据类型要容易得多。所以,现在就做你能安全做的。
fnvucqvd3#
索引的确切大小将取决于您有多少行,但也取决于索引中数据的外观。
如果数据中的每条记录减少1个字节,并且有10.000.000条记录,那么只能在磁盘上为表数据节省10mb的空间。添加一个索引会增加更多的索引,而b树中有空的空间,但这取决于实际数据的效率。
如果要节省空间,请确保该字段不可为null,因为即使用数据填充所有行,每个记录都有一个信息,说明可为null的字段是否包含数据。