从性能的角度考虑,使用UUID来作为聚簇索引则会很糟糕,它使得聚簇索引的插入变得完全随机,这是最坏的情况,使得数据没有任何聚集特性。

使用UUID主键插入行不仅花费的时间更长,而且索引占用的空间页更大。这一方面是由于主键字段更长,另一方面是由于页分裂和碎片导致的。

因为主键的值时顺序的,所以InnoDB把每一条记录都存储在上一条记录的后面,当本页中的记录满时,下一条记录就会插入到新的页中,一旦按照这种顺序的方式加载,主键页就会近似于别顺序的记录填满,这也正是所期望的结果。

因为新行的主键值不一定比之前插入的大,所以InnoDB无法简单的总是把新行插入到索引的最后,而是需要为新的行寻找合适的位置 (通常是已有数据的中间位置),并且分配空间。这会增加很多的额外工作,并导致数据分布不够优化,下面总结一些缺点:

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

所以使用InnoDB时,应该尽可能的按照主键顺序插入顺序,并且尽可能的使用单调递增的聚簇键的值来插入新行。