请问 mysql innodb uuid 做非聚集索引的问题

2018-07-04 10:22:02 +08:00
 taofuan

请问大家 mysql 数据库 innodb 引擎的一张表使用 uuid 当主键,默认就是聚集索引取消不掉,索性搞成了不加主键把字段做成 unique index,然后聚集索引没了,请问这样的话比较设置主键会有性能的提升吗?会带来新的问题吗?谢谢大家

4481 次点击
所在节点    MySQL
8 条回复
honeycomb
2018-07-04 10:34:52 +08:00
考虑用 type-1 UUID,它是自增的
sudodo
2018-07-04 12:12:48 +08:00
菜鸟回答一下:innodb 即使你不设置主键,也会有隐式主键的;

在这种情况下,如果 uuid 字段不是主键的话,该字段的索引都是二级索引,查询性能基本不会有任何提升;

但是把 uuid 索引设置成 unique index,在 Repeatable-Read 事务隔离级别下,对增删改的 sql 性能会有一定的提升;
taofuan
2018-07-04 13:10:31 +08:00
@sudodo 感谢回答,太专业啦
glacer
2018-07-04 16:29:59 +08:00
实际上如果拿 uuid 来做主键的话,性能会更差。
innodb 内部数据会按照主键来排序,如果是自增主键,插入数据时只需要不断在磁盘块后面追加即可,但如果是 uuid 做主键,每次插入会把该条数据插入到对应的排序位置中去,往往会造成大量的数据移动,造成磁盘块分裂,出现大量磁盘碎片。
watzds
2018-07-04 17:58:04 +08:00
@sudodo 二级索引为啥查询性能就没提升?
seven2016
2018-07-04 19:28:06 +08:00
高性能 mysql 有提到这个问题,避免 uuid 作聚簇索引,最简单的方法是设置一个代理主键,例如自增 id
wangwangleilei
2018-07-05 10:26:06 +08:00
innodb 必须有一个聚簇索引( B+树决定),如果没有主键会用合适的 unique key 做聚簇索引,如果没有合适的 unique key,会创建一个列来存储 ID 以构造一个隐藏的聚簇索引。

所以 uuid 字段现在仍然是聚簇索引,查询性能不会有变化。但是现在插入对聚簇索引而言不再是顺序插入,会涉及到页分裂,时间长了就会有碎片,除非定时整理,否则长此以往性能会下降。待插入的页因为是随机的,可能已写入磁盘,这里会有大量的 random IO。

另外其他二级索引的叶子节点现在要存储 uuid 了,需要更多的存储空间,能加载到内存中的索引节点个数会减少,理论上使用二级索引的查询会变慢。

总之,不是个好主意。
hrcyl
2019-08-23 19:00:47 +08:00
@wangwangleilei 感谢你的回答,很完整

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/467989

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX