MySQL:char(4) 比 smallint(5, unsigned) 更快的性能差异
MySQL: Performance difference between char(4) faster then smallint(5, unisgned)
我是 运行 MySQL 5.7.30-0ubuntu0.16.04.1-log 服务器,我可以选择将其保存为 char(4) 还是 smallint(5, unsigned) .
该列将有一个主索引,该键将用作跨表的引用。
什么更快? Char 还是 Int?
无符号 SMALLINT
值使用两个字节,值在 [0, 65535] 范围内。 CHAR(4)
值占用四个字节。因此,索引 SMALLINT
值将产生较小的索引。越小越快。此外,字符列上的索引通常内置了各种字符集和不区分大小写的猴子业务,这也需要时间和 space.
但是,对于最多 65K 行的 table,此选择的影响非常小,您将难以衡量它。如果你构建了一些难以调试的东西,那么你将花费宝贵的时间,而且调试它所花费的计算机时间是它节省的时间的一万倍。
设计您的 table 使其与您的应用相匹配。如果您使用的是四位数号码,请使用 SMALLINT
。
下一个处理你的代码的人(即使那个人是一年后的你)会感谢你清晰的实现。
请记住 MySQL 会忽略 INT 声明中括号中的数字。 SMALLINT(4)
、SMALLINT(5)
和 SMALLINT
的意思完全相同。 MySQL 使用本机处理器整数数据类型:TINYINT
是一个 8 位数字,SMALLINT
一个 16 位数字,INT
一个 32 位数字,BIGINT
一个 64 位数字。同样,FLOAT
是一个 32 位 IEEE 754 浮点数,而 DOUBLE
是一个 64 位浮点数。位数 SMALLINT(4)
是对 SQL 标准兼容性的认可。
正如 O. Jones 所提到的,SMALLINT 会更快,space-高效。
这与以下答案有关:mysql-char-vs-int
此外,MySQL 文档:
CHAR and VARCHAR types
Integer Types
案例 1:CHAR(4)
和 SMALLINT
之间的差异是微不足道的。它不应该影响您对数据类型的选择。相反,使用与数据匹配的数据类型。
情况 2:如果您比较 TINYINT
和 VARCHAR(255)
,答案可能不同。请注意,选择之间存在更大的差异。
案例 3:如果选择归结为是否 "normalize" 列,则两种方式都有争论。我更喜欢对 country_code
使用 CHAR(2)
,而不是为了缩小到 TINYINT
而进行标准化。额外规范化的开销总是(?)超过节省的 space。
另一个考虑因素:table 上有多少个辅助键?您将加入多少其他 table?
情况 4:PRIMARY KEY(big_string)
但没有辅助键。切换到 int 可能没有优势。
情况 5:由于辅助密钥包含 PK,请考虑:
PRIMARY KEY(big_string),
INDEX(foo),
INDEX(bar)
对比
PRIMARY KEY(id), -- surrogate AUTO_INCREMENT
INDEX(big_string),
INDEX(foo),
INDEX(bar)
后者占用的磁盘较少space。
另一个考虑因素:获取一行比比较一个 int 或 string 的成本要高得多。我的意思是你不应该担心比较性能;优化时应该放眼大局。
案例 6:美国 5 位邮政编码。 CHAR(5)
(5 个字节)是合理的。 MEDIUMINT(5) UNSIGNED ZEROFILL
(3 个字节)更好,因为它做得更好。 (*INT(n)
有意义的情况非常罕见。)
争论还在继续。
我是 运行 MySQL 5.7.30-0ubuntu0.16.04.1-log 服务器,我可以选择将其保存为 char(4) 还是 smallint(5, unsigned) . 该列将有一个主索引,该键将用作跨表的引用。
什么更快? Char 还是 Int?
无符号 SMALLINT
值使用两个字节,值在 [0, 65535] 范围内。 CHAR(4)
值占用四个字节。因此,索引 SMALLINT
值将产生较小的索引。越小越快。此外,字符列上的索引通常内置了各种字符集和不区分大小写的猴子业务,这也需要时间和 space.
但是,对于最多 65K 行的 table,此选择的影响非常小,您将难以衡量它。如果你构建了一些难以调试的东西,那么你将花费宝贵的时间,而且调试它所花费的计算机时间是它节省的时间的一万倍。
设计您的 table 使其与您的应用相匹配。如果您使用的是四位数号码,请使用 SMALLINT
。
下一个处理你的代码的人(即使那个人是一年后的你)会感谢你清晰的实现。
请记住 MySQL 会忽略 INT 声明中括号中的数字。 SMALLINT(4)
、SMALLINT(5)
和 SMALLINT
的意思完全相同。 MySQL 使用本机处理器整数数据类型:TINYINT
是一个 8 位数字,SMALLINT
一个 16 位数字,INT
一个 32 位数字,BIGINT
一个 64 位数字。同样,FLOAT
是一个 32 位 IEEE 754 浮点数,而 DOUBLE
是一个 64 位浮点数。位数 SMALLINT(4)
是对 SQL 标准兼容性的认可。
正如 O. Jones 所提到的,SMALLINT 会更快,space-高效。
这与以下答案有关:mysql-char-vs-int
此外,MySQL 文档:
CHAR and VARCHAR types
Integer Types
案例 1:CHAR(4)
和 SMALLINT
之间的差异是微不足道的。它不应该影响您对数据类型的选择。相反,使用与数据匹配的数据类型。
情况 2:如果您比较 TINYINT
和 VARCHAR(255)
,答案可能不同。请注意,选择之间存在更大的差异。
案例 3:如果选择归结为是否 "normalize" 列,则两种方式都有争论。我更喜欢对 country_code
使用 CHAR(2)
,而不是为了缩小到 TINYINT
而进行标准化。额外规范化的开销总是(?)超过节省的 space。
另一个考虑因素:table 上有多少个辅助键?您将加入多少其他 table?
情况 4:PRIMARY KEY(big_string)
但没有辅助键。切换到 int 可能没有优势。
情况 5:由于辅助密钥包含 PK,请考虑:
PRIMARY KEY(big_string),
INDEX(foo),
INDEX(bar)
对比
PRIMARY KEY(id), -- surrogate AUTO_INCREMENT
INDEX(big_string),
INDEX(foo),
INDEX(bar)
后者占用的磁盘较少space。
另一个考虑因素:获取一行比比较一个 int 或 string 的成本要高得多。我的意思是你不应该担心比较性能;优化时应该放眼大局。
案例 6:美国 5 位邮政编码。 CHAR(5)
(5 个字节)是合理的。 MEDIUMINT(5) UNSIGNED ZEROFILL
(3 个字节)更好,因为它做得更好。 (*INT(n)
有意义的情况非常罕见。)
争论还在继续。