MySQL BIGINT(20) 与 Varchar(31) 性能对比

MySQL BIGINT(20) vs Varchar(31) performance

我读过像 23423423423423423637 这样的 bigint 对于 primare unique key 比像 961637593864109_412954765521130 的 varchar 更好但是 how 当有 100 万行时差异很大当我永远不会排序但只有 select/update 一行时。使用 varchar 对我来说会舒服得多,当性能差异低于 30% 或任何其他值时,我将继续使用它。我找不到任何基准。

这确实需要衡量,我们可以根据我们所知道的和我们假设的做出一些 "guesses",但这些只是猜测。

你没有提到这个 table 是 InnoDB,还是动态行的 MyISAM,或者固定长度行的 MyISAM。这会有所不同。

但对于像您发布的那样的值,'961637593864109_412954765521130'(31 个字符),假设您使用的是单字节字符集(例如 latin1)或将这些特定字符编码为单字节的字符集(例如 utf8)...

对于 InnoDB 和 MyISAM 动态格式,该行有 31+1-8=24 个额外字节。 (BIGINT 适合 8 个字节,31 个字符的 VARCHAR(31) 值将使用 32 个字节。)

对于具有固定长度行的 MyISAM table,这将是每行 23 个字节的差异。 (Space保留全部31个字符,长度不用存)

该主键值也将在每个索引中重复,因此每个索引也增加了 space。

假设您的 table 行使用 BIGINT 时为 120 字节,而使用 VARCHAR 时行为 144 字节,则增加 20%。您的行越大,增加的百分比就越小,反之亦然。

对于 1,000,000 行(我很想说 "one meelyun rows" 就像邪恶博士将他的小指放在嘴角并说 "one million dollars" 一样),每个额外的 24 个字节行总计约 24MB。

但这并不是那么容易。就 InnoDB space 而言,这是将行 "fit" 放入块中的可能性的问题。平均行大小越大,一个块中的空闲量就越大 space。

如果您除了将行存储在磁盘上之外不对这些行执行任何操作,那么它实际上只是增加了磁盘 space,以及额外的时间和 space 用于备份。


如果块中包含的“144 字节”行数与“120 字节”行数相同,那么您将不会在 space 中看到任何差异。但是,如果一个块中适合的行更少,那就是更多的块,InnoDB 缓冲池中更多 space,更多 i/o,等等


对于单个行的查询,无论是通过主键值,还是通过一些其他唯一索引查找,差异都可以忽略不计。

如果您正在处理更大的结果集,那么这就是准备结果集的额外内存,以及传输到客户端的额外字节等。


如果 VARCHAR 键的设计方式是 "groups" 一起访问的行具有键值的相同前导部分,那么对于 InnoDB,实际上可能会有一些性能改进。那是因为主键是簇键...满足查询所需的行在同一个块中的可能性要大得多,而不是分散在一堆块上。

反之,如果有插入和删除操作,一些块中会有更多空闲space。 (通过删除,已删除行的 space 保留在块中;要重用它,您需要插入一个具有相同键值的行(或者至少一个键值足够接近以使其着陆在同一个块中。)通过随机插入,我们将得到块拆分。