请问大家 mysql 数据库 innodb 引擎的一张表使用 uuid 当主键,默认就是聚集索引取消不掉,索性搞成了不加主键把字段做成 unique index,然后聚集索引没了,请问这样的话比较设置主键会有性能的提升吗?会带来新的问题吗?谢谢大家
1
honeycomb 2018-07-04 10:34:52 +08:00 via Android 1
考虑用 type-1 UUID,它是自增的
|
2
sudodo 2018-07-04 12:12:48 +08:00 4
菜鸟回答一下:innodb 即使你不设置主键,也会有隐式主键的;
在这种情况下,如果 uuid 字段不是主键的话,该字段的索引都是二级索引,查询性能基本不会有任何提升; 但是把 uuid 索引设置成 unique index,在 Repeatable-Read 事务隔离级别下,对增删改的 sql 性能会有一定的提升; |
4
glacer 2018-07-04 16:29:59 +08:00 1
实际上如果拿 uuid 来做主键的话,性能会更差。
innodb 内部数据会按照主键来排序,如果是自增主键,插入数据时只需要不断在磁盘块后面追加即可,但如果是 uuid 做主键,每次插入会把该条数据插入到对应的排序位置中去,往往会造成大量的数据移动,造成磁盘块分裂,出现大量磁盘碎片。 |
6
seven2016 2018-07-04 19:28:06 +08:00
高性能 mysql 有提到这个问题,避免 uuid 作聚簇索引,最简单的方法是设置一个代理主键,例如自增 id
|
7
wangwangleilei 2018-07-05 10:26:06 +08:00 1
innodb 必须有一个聚簇索引( B+树决定),如果没有主键会用合适的 unique key 做聚簇索引,如果没有合适的 unique key,会创建一个列来存储 ID 以构造一个隐藏的聚簇索引。
所以 uuid 字段现在仍然是聚簇索引,查询性能不会有变化。但是现在插入对聚簇索引而言不再是顺序插入,会涉及到页分裂,时间长了就会有碎片,除非定时整理,否则长此以往性能会下降。待插入的页因为是随机的,可能已写入磁盘,这里会有大量的 random IO。 另外其他二级索引的叶子节点现在要存储 uuid 了,需要更多的存储空间,能加载到内存中的索引节点个数会减少,理论上使用二级索引的查询会变慢。 总之,不是个好主意。 |
8
hrcyl 2019-08-23 19:00:47 +08:00
@wangwangleilei 感谢你的回答,很完整
|