为啥不推荐uuid作为Mysql的主键呢

为啥不推荐使用uuid作为Mysql数据库的主键呢

​ 在mysql中设计表的时候,mysql官方并不推荐使用uuid或者不连续不重复的雪花id,而是推荐使用连续自增的主键id。

​ 官方推荐的是auto_increment。主要原因是uuid在数据量较大的情况下,效率直线下滑。

使用uuid和自增id的索引结构对比

使用自增id的内部结构

​ 自增的主键的值是顺序的,所以Innodb把每一条记录都存储在一条记录的后面。当达到页面的最大填充因子的时候(innodb是15/16)

​ 下一条记录会写入新的页中,一旦数据按照这种顺序的方式加载,主键页就会近乎于顺序的记录填满,提升了页面的最大填充率,不会有页的浪费

​ 新插入的行一定会在原有的最大数据行的下一行,mysql定位和寻址很快,不会为计算新行的位置而做出额外的消耗

​ 减少了页分裂和碎片的产生

缺点
  • 别人容易根据自增的id爬取数据库,从而分析数据
  • 对于高并发的负载,innodb在按主键进行插入的时候会造成明显的锁争用,主键的上界会成为争抢的热点。因为所有的插入都发生在这里,并发插入会导致间隙锁竞争
  • @Auto_Increment锁机制会造成自增锁的抢夺,有一定的性能损失

使用uuid的索引内部结构

​ 因为uuid毫无规律可言,新值和旧值大小无法确定,所以需要innodb要为新行寻找新的合适的位置从而来分配新的空间。会导致以下几个问题:

  • 写入的目标页很可能已经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中,innodb在插入之前不得不先找到并从磁盘读取目标页到内存中,这就导致了大量的随机IO
  • 因为写入是乱序的,所以innodb不得不频繁的做页分裂操作,以便为新的行分配空间,页分裂导致移动大量的数据,一次插入最少修改三个页以上
  • 由于频繁的页分裂,页会变得稀疏并被不规则的填充,最终会倒是数据有碎片

把随机值(uuid和雪花id)载入到聚簇索引(innodb默认的索引类型)以后,有时候会需要做一次OPTIMEIZE TABLE来重建表并优化页的填充,这将又需要一定的时间消耗。

总结:

​ 使用innodb应该尽可能的按主键的自增顺序插入,并且尽可能使用单调的增加的聚簇键的值来插入新行

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/108596275