在InnoDB表中按主键顺序插入行

​ 在主键的问题上,最简单也是大多数情况下最适用的方法就是使用AUTO_INCREMENT列。这样保证了数据行是按顺序写入的,对于根据主键做关联操作的性能也会更好。

​ 最好避免随机的(不连续且值的分布范围非常大)聚簇索引,特别是对I/O密集型的应用,例如,从性能的角度考虑,使用UUID来作为聚簇索引是一个很糟糕的选择:它使得聚簇索引的插入变得完全随机,每次插入数据都有可能会重构主键索引树,不仅仅是性能的损失,用UUID做主键还会导致索引变得很大,因为InnoDB的二级索引的叶子节点保存的是索引值+该索引值对应的主键。另一个造成索引很大的原因是因为页分裂和碎片。由于写入是乱序的InnoDB不得不频繁的做页分裂操作(把数据从原本的位置上向后移动,为新数据的插入创造空间)。

​ 但是AUTO_INCERMENT并不是银弹,在高并发的情况下,数据大量写入,InnoDB的主键插入顺序可能会造成明显的争用,主键的上界成为“热点”。因为所有的插入都发生在这里,所以并发插入可能会导致间隙锁竞争。在应用层解决这个问题的选择之一是采用雪花算法生成主键,因为雪花算法生成的值受41bit的时间戳影响,基本上可以认为它是自增的,避免了主键索引树的频繁重构,同时细粒度的时间戳也让竞争插入出现的可能性降低。