UUID在MySQL中的性能?

我们正在考虑使用UUID值作为MySQL数据库的主键。 插入的数据是从数十,数百或甚至数千个远程计算机中生成的,并且以每秒100至40,000个插入的速率插入,我们将永远不会做任何更新。

在我们开始剔除数据之前,数据库本身通常会达到大约50M记录,所以不是一个庞大的数据库,但也不是很小。 我们也计划在InnoDB上运行,尽管如果我们正在做的事情有更好的引擎,我们可以改变这一点。

我们已经准备好使用Java的Type 4 UUID,但在测试中已经看到一些奇怪的行为。 首先,我们将存储为varchar(36),现在我意识到使用二进制文件(16)会更好 - 尽管我不确定会好多少。

更大的问题是:当我们有5千万条记录时,这个随机数据有多严重地搞砸了索引? 如果我们使用例如最左边的比特是时间戳的类型1 UUID,我们会更好吗? 或者,也许我们应该完全抛弃UUID并考虑auto_increment主键?

我正在寻找关于不同类型的UUID在MySQL中作为索引/主键存储时的性能的一般想法/提示。 谢谢!


UUID是一个通用唯一ID。 这是你应该在这里考虑的普遍部分。

你真的需要这些ID是普遍唯一的吗? 如果是这样,那么UUID可能是您唯一的选择。

我强烈建议如果你使用UUID,你将它们存储为一个数字而不是字符串。 如果你有50M +的记录,那么存储空间的节省将会提高你的性能(尽管我不能说多少)。

如果你的ID不需要是全局唯一的,那么我认为你可以做得更好,然后使用auto_increment,它保证了ID在表中是唯一的(因为这个值每次都会增加)


在我的工作中,我们使用UUID作为PK。 我可以告诉你的经验是不要使用它们作为PK(顺便提一下SQL Server)。

这是其中一件事情,即当你少于1000条记录的时候,没关系,但是当你拥有数百万的时候,这是你能做的最糟糕的事情。 为什么? 由于UUID不是顺序的,因此每次插入新记录时,MSSQL都需要查看正确的页面以插入记录,然后插入记录。 这样做的真正丑陋的后果是,页面的大小不一样,并且它们最终会碎片化,所以现在我们必须定期去除碎片。

当你使用一个自动增量时,MSSQL将总是进入最后一页,并且你最终得到相同大小的页面(理论上),所以选择这些记录的性能要好得多(因为INSERT不会阻止表/页太长)。

但是,使用UUID作为PK的一大优点是,如果我们有数据库集群,合并时不会发生冲突。

我会推荐以下模型:1. PK INT标识2.附加列自动生成为UUID。

通过这种方式,合并过程是可能的(UUID将是您的REAL键,而PK只是临时性的东西,可以让您获得良好的性能)。

注意:最好的解决方案是使用NEWSEQUENTIALID(就像我在评论中所说的那样),但对于没有太多时间重构(甚至更糟糕,不控制所有插入)的遗留应用程序,这是不可能的。 但实际上到2017年,我会说这里的最佳解决方案是NEWSEQUENTIALID或者与NHibernate一起做Guid.Comb。

希望这可以帮助


需要考虑的一点是Autoincrements一次只能生成一个,不能使用并行解决方案解决。 使用UUID的斗争最终归结为你想要实现的目标与你可能牺牲的目标。

在表现上,简单地说:

像上面那样的UUID长度为36个字符,包括破折号。 如果你存储这个VARCHAR(36),你会大大降低比较性能。 这是你的主要关键,你不希望它变慢。

在它的比特级别,UUID是128位,这意味着它将适合16个字节,注意这不是人类可读的,但它将保持低存储,并且只比32位int大4倍,或者2比64位整数大。 我将使用VARBINARY(16)理论上,这可以在没有很多开销的情况下工作。

我建议阅读以下两篇文章:

  • 布赖恩“克罗”阿克的闲置思想 - 神话,GUID与自动增量
  • 要UUID还是不要UUID?
  • 我估计在两者之间,他们回答你的问题。

    链接地址: http://www.djcxy.com/p/91471.html

    上一篇: UUID performance in MySQL?

    下一篇: Generate a UUID on iOS from Swift