【问题标题】:MySQL BIGINT(20) vs Varchar(31) performanceMySQL BIGINT(20) 与 Varchar(31) 性能对比
【发布时间】:2015-01-09 16:31:42
【问题描述】:

我已经读过,像 23423423423423423637 这样的 bigint 对于primare唯一键比像 961637593864109_412954765521130 这样的 varchar 更好,但是当我永远不会排序而只选择/时,当有 100 万行时,差异有多大更新一行。使用 varchar 对我来说会更舒服,当性能差异低于 30% 或任何值时,我会继续使用它。我找不到任何基准。

【问题讨论】:

  • 猜测,可以忽略不计
  • 我没有数字,但它可能很重要。主键用于对表数据进行排序,并包含在您创建的每个索引中。索引的目的是读取表的一小部分以快速识别相关记录。如果您的主键占行数据的足够大百分比,您将强制系统进行表扫描。话虽如此,使用由 36 个字节组成的 UniqueIdentifier 是很常见的。
  • 这两个数字在您的 VARCHAR 中代表什么?您可以将两个有意义的数字列组合成一个主键。这样可以防止将随机数据添加为主键,从而保持数据的一致性。
  • 是的,但我需要先检查 id 组合是否已经存在,然后再进行进一步操作。还有更多难以解释的事情,使用 varchar 会更舒服。例如在 100 万行时,它的重要性有多大?我无法从你的解释中猜到:/

标签: mysql performance benchmarking


【解决方案1】:

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

您没有提及此表是 InnoDB,还是具有动态行的 MyISAM,或具有固定长度行的 MyISAM。这会有所作为。

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

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

对于具有固定长度行的 MyISAM 表,这将是每行 23 个字节的差异。 (空间为所有 31 个字符保留,长度不必存储。)

该主键值也将在每个索引中重复,因此每个索引的空间也会增加。

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

对于 1,000,000 行(我想说“一个 meelyun 行”,就像邪恶博士将他的小指放在嘴角说“一百万美元”一样)每行额外的 24 个字节总计大约 24MB。

但这并不是那么容易。就 InnoDB 空间而言,这是行如何“适合”到块中的问题。平均行大小越大,块中的可用空间量就越大。

如果您除了将行存储在磁盘上之外不做任何事情,那么实际上只是增加了磁盘空间,并增加了备份的时间和空间。


如果块中的“144 字节”行数与“120 字节”行数相同,那么您不会看到空间差异。但是如果一个块中容纳的行数越少,那么块就越多,InnoDB 缓冲池中的空间就越大,I/O 就越多,等等。


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

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


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

反之,如果执行了插入和删除,某些块中将有更多的可用空间。 (通过删除,已删除行的空间保留在块中;要重用它,您需要插入具有相同键值的行(或至少一个键值足够接近以使其位于同一块中) .) 通过随机插入,我们将得到块分割。

【讨论】:

    猜你喜欢
    • 2012-03-11
    • 2010-10-05
    • 2011-03-09
    • 2016-09-29
    • 2017-09-19
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    相关资源
    最近更新 更多