BIGINT与INT在mysql性能方面的比较

58

我正在尝试找出,如果我将主键更改为BIGINT(20),是否会降低表的性能。目前,我正在使用INT(7),并且有大量ID(7或8位数字)的300,000个条目

我已经进行了很多搜索,但只发现它使用更多的磁盘空间(这是显而易见的)。

所有我的ID现在都有7位数字,但是我的客户想要更改为8位数字。未来我将无法轻松更改软件,因此我想现在就使用BIGINT(20)以防万一。即使我现在还不需要,使用BIGINT会使性能变差吗?

有没有经验丰富的人可以提供有关速度和性能方面的建议?

2个回答

125

回答您的问题:是的,它的性能会下降。显然,类型越大,表越大,查询就会越慢(更多的I/O、更大的索引、更长的访问时间,结果不太可能适合各种缓存等)。因此,一个经验法则是:始终使用最小的类型以满足您的需求。

话虽如此,性能并不重要。为什么?因为当您达到溢出INT的程度时,BIGINT是唯一的解决方案,您将不得不接受它。此外,在那个点上(考虑到您使用的是自增的PK,您将拥有超过4 十亿行),您将面临更大的性能问题,而与INT相比,BIGINT的开销将是您最不用担心的问题。

因此,请考虑以下几点:


4
这句话的意思是:“这就是我要说的一切。除非你处理大量数据(而30万个条目并不算多),否则几乎没有可能达到INT字段的限制。此外,正如在这里提到的那样,(7)并不能真正限制字段存储的内容。如果你将它设置为UNSIGNED,你仍然有43亿的限制。” - Simon at My School Portal
1
虽然它是被导入的,但这并不妨碍您使用AUTO_INCREMENT - 在一系列插入之后,AI值会自动设置为PK的最大值(如果没有,您可以使用ALTER进行更改)。现在,如果您确实需要BIGINT,因为您可能有超过10位数字的数字(例如序列号),那么是的,它会稍微不那么高效。如果您真的非常担心并且有巨大的流量,您可以使用单独的(小)自动增量PK,并将您的BIGINT存储为UNIQUE INDEX(但坦率地说,我认为这不值得麻烦)。 - rlanvin
7
我认为在这种情况下,额外开销很小,你不会注意到它。(我正在使用BIGINT作为主键处理超过4000万行的表格,并没有遇到问题。) - rlanvin
1
我将这个问题添加到了我的回答中,因为这里的评论已经太长了:有人在某个地方真正测试过它吗?使用“仅”300,000条记录和次优的字段类型的性能如何? - rubo77
1
@rlavin:你能把这句话加到你的回答里吗?“在你的情况下,只有30万行数据,开销很小,你不会注意到它。” - rubo77
显示剩余6条评论

7

不希望复活僵尸,但“现代”mysql使用的列类型是serial,它是bigint(20) unsigned NOT NULL AUTO_INCREMENT - 这肯定表明mysql将要(或正在)优化使用bigint作为主键。

此外,与其使用serial,varbinary(16) primary允许使用uuid_short()作为主键(而不是uuid - 因为它是一个字符串,非常慢),这有一个特性,确保每个记录在整个数据库(甚至网络)中具有唯一的键。

但请注意 - 一些强制转换会将bigint降级为int,导致糟糕的结果。例如,如果您正在比较字符串表示与big int,则可能会发现您得到错误的结果。因此,必须使用二进制进行比较...例如:

where id = binary id_str

个人而言,我会把这个称作未修复的漏洞...

1
你能否提供更多关于“建议使用bigint作为主键来优化mysql”的信息链接?这里有更多的信息会很好。 - Sebastian Schürmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接