Pat*_*ody 77 mysql performance uuid innodb sequence
我们正在考虑使用UUID值作为MySQL数据库的主键.插入的数据是从数十台,数百台甚至数千台远程计算机生成的,并以每秒100-40,000次插入的速率插入,我们永远不会进行任何更新.
在我们开始剔除数据之前,数据库本身通常会达到大约50M的记录,因此不是一个庞大的数据库,但也不是很小.我们也计划在InnoDB上运行,但如果我们正在做的事情有更好的引擎,我们愿意改变它.
我们已准备好使用Java的Type 4 UUID,但在测试中已经看到了一些奇怪的行为.首先,我们将存储为varchar(36),现在我意识到我们最好使用二进制(16) - 尽管我不确定会有多好.
更大的问题是:当我们拥有50M记录时,这个随机数据对索引的影响有多大?如果我们使用例如最左边的位被加时间戳的1型UUID,我们会更好吗?或者我们应该完全抛弃UUID并考虑auto_increment主键?
我正在寻找关于不同类型的UUID在MySQL中作为索引/主键存储时的性能的一般想法/提示.谢谢!
Kat*_*uiz 73
在我的工作中,我们使用UUID作为PK.我从经验中可以告诉你的是,不要将它们用作PK(顺便提一下SQL Server).
当你记录的记录少于1000时,它就是其中之一;没问题,但是当你拥有数百万时,这是你能做的最糟糕的事情.为什么?因为UUID不是顺序的,所以每次插入新记录时MSSQL都需要查看正确的页面以插入记录,然后插入记录.这个真正丑陋的结果是页面最终都以不同的大小结束,最终会碎片化,所以现在我们必须定期进行去碎片化.
当你使用自动增量时,MSSQL总会转到最后一页,你最终得到同样大小的页面(理论上),所以选择那些记录的性能要好得多(也因为INSERT不会阻塞表/页面)太长).
但是,使用UUID作为PK的一大优势是,如果我们有DB集群,合并时就不会有冲突.
我建议使用以下模型:1.PK INT Identity 2.附加列自动生成为UUID.
这样,合并过程是可能的(UUID将是您的REAL键,而PK只是暂时性的,可以提供良好的性能).
注意:最好的解决方案是使用NEWSEQUENTIALID(就像我在评论中所说的那样),但是对于没有太多时间重构的遗留应用程序(更糟糕的是,不控制所有插入),这是不可能的.但实际上到2017年,我会说这里最好的解决方案是NEWSEQUENTIALID或者用NHibernate做Guid.Comb.
希望这可以帮助
Dan*_*umb 32
UUID是通用唯一ID.这是你应该在这里考虑的普遍部分.
你真的需要这些ID是普遍独一无二的吗?如果是这样,那么UUID可能是您唯一的选择.
我强烈建议,如果你做使用的UUID,您将它们保存为一个数字,而不是作为一个字符串.如果您有50M +记录,那么节省存储空间将提高您的性能(虽然我不能说多少).
如果您的ID不需要是普遍唯一的,那么我认为您可以做得更好,只需使用auto_increment,这可以保证ID在表中是唯一的(因为每次都会增加值)
Kyl*_*ndo 25
需要考虑的是,自动增量是一次生成一个,并且无法使用并行解决方案来解决.使用UUID的斗争最终取决于你想要实现的目标与你可能牺牲的目标.
关于表现,简要说明:
像上面这样的UUID是36个字符长,包括破折号.如果存储此VARCHAR(36),则会显着降低比较性能.这是你的主键,你不希望它变慢.
在它的位级别,UUID是128位,这意味着它将适合16个字节,注意这不是人类可读的,但它将保持低存储,并且只比32位int大4倍,或2大于64位int的时间.我将使用VARBINARY(16)从理论上讲,这可以在没有大量开销的情况下工作.
我建议阅读以下两篇文章:
我估计两者之间,他们回答你的问题.
小智 5
我倾向于避免使用UUID,因为存储起来很痛苦并且使用它作为主键是一种痛苦,但是有一些优点.主要的是它们是独一无二的.
我通常使用双键字段解决问题并避免使用UUID.
收集器=独特的机器分配
ID =收集器收集的记录(auto_inc字段)
这给了我两件事.自动加入字段的速度和数据的唯一性在收集并组合在一起后存储在中心位置.我也知道在浏览收集数据时,这通常对我的需求非常重要.
我在为客户决定使用UUID处理其他数据集时遇到了很多情况,但是仍然有一个用于收集数据的字段,这实际上是浪费精力.只需使用两个(或更多,如果需要)字段作为您的密钥真的有帮助.
我刚刚看到使用UUID的太多性能命中.他们觉得自己像个骗子......