Space 在将列类型从 INT 更改为 SMALLINT 和 TINYINT 后,在 MyISAM table 中增加
Space increased in MyISAM table after change column type from INT to SMALLINT and TINYINT
我正在尝试减少我的数据库 table 占用的 space 并优化我的系统性能。我有兴趣专门优化一些具有大量数据的 MyISAM table。
所以我改变了列类型如下:
- 从 INT(11) 到 BIT(1) 或 TINYINT(3) 或 SMALLINT(6) 或 MEDIUMINT(9)
- 从 VARCHAR(...) 到 CHAR(x),其中 x 是有用字符的最小数量
但结果出乎意料
我在更改前后 运行 以下查询:
SELECT
table_name AS "Table",
round(((data_length + index_length) / 1024 / 1024), 2) "Size in MB" FROM information_schema.TABLES WHERE table_schema =
"my_schema"
AND table_name = "my_table";
结果:
- 558 Mb 之前
- 在 673,96 Mb
之后
增加了space。为什么?
编辑:
问题是 CHAR 转换。在我的例子中,VARCHAR 占用较少 space 因为字段不是固定维度的,所以固定的 CHAR 字段需要更多 space.
使用 VARCHAR,我的 table 占用 444 Mb.
INT
更改应该有所帮助。
VARCHAR
更改应该会造成伤害。
不要使用 CHAR
,除非您 (1) 数据是恒定长度的,并且 (2) CHARACTER SET
是合适的。
VARCHAR
实现为 1 或 2 个字节的长度,加上每个字符串所需的字节数。
CHAR(N)
总是占用 M*N 个字节:M bytes/character 取决于字符集:ascii/latin1: 1; utf8: 3, utf8mb4: 4.
在极少数情况下 CHAR
实际上比 VARCHAR
更好。这里有一些:
country_code CHAR(2) CHARACTER SET ascii,
md5 CHAR(32) CHARACTER SET ascii, -- packing into BINARY(16) would be tighter
zip_code CHAR(5) CHARACTER SET ascii, -- MEDIUMINT(5) UNSIGNED ZEROFILL would be tighter
uuid CHAR(36) CHARACTER SET ascii, -- Could be packed into BINARY(16)
嗯……暂时能想到的就这些了
而且,不,MyISAM 不会受益于"FIXED"而不是"DYNAMIC",除非在极少数情况下。由于VARCHAR
小,所以I/O少; I/O 是处理数据的 主要 成本。
下一步:忘掉 MyISAM,升级到 InnoDB。
我正在尝试减少我的数据库 table 占用的 space 并优化我的系统性能。我有兴趣专门优化一些具有大量数据的 MyISAM table。
所以我改变了列类型如下:
- 从 INT(11) 到 BIT(1) 或 TINYINT(3) 或 SMALLINT(6) 或 MEDIUMINT(9)
- 从 VARCHAR(...) 到 CHAR(x),其中 x 是有用字符的最小数量
但结果出乎意料
我在更改前后 运行 以下查询:
SELECT table_name AS "Table", round(((data_length + index_length) / 1024 / 1024), 2) "Size in MB" FROM information_schema.TABLES WHERE table_schema = "my_schema" AND table_name = "my_table";
结果:
- 558 Mb 之前
- 在 673,96 Mb
增加了space。为什么?
编辑:
问题是 CHAR 转换。在我的例子中,VARCHAR 占用较少 space 因为字段不是固定维度的,所以固定的 CHAR 字段需要更多 space.
使用 VARCHAR,我的 table 占用 444 Mb.
INT
更改应该有所帮助。
VARCHAR
更改应该会造成伤害。
不要使用 CHAR
,除非您 (1) 数据是恒定长度的,并且 (2) CHARACTER SET
是合适的。
VARCHAR
实现为 1 或 2 个字节的长度,加上每个字符串所需的字节数。
CHAR(N)
总是占用 M*N 个字节:M bytes/character 取决于字符集:ascii/latin1: 1; utf8: 3, utf8mb4: 4.
在极少数情况下 CHAR
实际上比 VARCHAR
更好。这里有一些:
country_code CHAR(2) CHARACTER SET ascii,
md5 CHAR(32) CHARACTER SET ascii, -- packing into BINARY(16) would be tighter
zip_code CHAR(5) CHARACTER SET ascii, -- MEDIUMINT(5) UNSIGNED ZEROFILL would be tighter
uuid CHAR(36) CHARACTER SET ascii, -- Could be packed into BINARY(16)
嗯……暂时能想到的就这些了
而且,不,MyISAM 不会受益于"FIXED"而不是"DYNAMIC",除非在极少数情况下。由于VARCHAR
小,所以I/O少; I/O 是处理数据的 主要 成本。
下一步:忘掉 MyISAM,升级到 InnoDB。