最近看了一篇文章深入分析mysql为什么不推荐使用uuid或者雪花id作为主键
文章通过实验分布测试自增主键、UUID主键、雪花算法生成主键测试总结,在随着数据量到达百万级以后,三种主键的插入效率:自增主键 > 雪花算法生成主键 > UUID主键;
究其原因:
- 自增主键按顺序插入,页面按顺序填充,不浪费空间;减少页分裂、碎片的产生;MySQL 行记录的定位和寻址很快;
- UUID主键插入,无顺序,数据分布离散;随机IO寻址和页定位;页分裂;数据碎片;
- 雪花算法,自增有序,适合分布式环境,数据量大时,效率更高;
该算法生成19位的long型有序数字,MySQL中用bigint来存储(bigint长度为20位),
导致主键索引空间会很大,这样二级索引占用空间也会很大(InnoDB引擎),MySQL有限的缓冲区,存储的索引与数据会减少,磁盘IO的概率也会增加。
最佳实践:使用InnoDB引擎下应该尽可能的按主键的自增顺序插入,并且尽可能使用单调的增加的聚簇键的值来插入新行,此主键与业务无关,只是用来做主键。
避免主键被人利用,再新增业务主键,比如订单号、身份证号、手机号等...
是否需要考虑在高并发下InnoDB在按主键进行插入的时候会造成明显的锁争用,主键的上界会成为争抢的热点,因为所有的插入都发生在这里,并发插入会导致间隙锁竞争,待研究。。。
参考:
数据库,主键为何不宜太长长长长长长长长?