聚集(聚簇)索引、非聚集(非聚簇)索引、主键自增对聚簇索引的影响

目录

聚簇索引

非聚簇索引

二级索引

以Mysql的InnoDB为例

主键自增对聚簇索引的好处

主键随机对聚簇索引的坏处


 

首先,聚集和聚簇只是翻译不同而已,是一个东西,其实挺蠢的

聚簇索引

索引和数据存储在一块( 都存储在同一个B*tree 中)。 一般主键索引都是聚餐索引。

Mysql中InnoDB引擎的主键索引为聚簇索引,MyISAM存储引擎采用非聚集索引。

因为无法同时把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引(不过,覆盖索引可以模拟多个聚簇索引的情况)。

非聚簇索引

索引数据和存储数据是分离的,索引和数据指针地址存储在一块。

二级索引

也叫辅助索引,也挺蠢的

二级索引存储的是记录的主键,而不是数据存储的地址,所以也称之为聚簇索引的二级索引。

以Mysql的InnoDB为例

主键索引是聚簇索引。

唯一索引、普通索引、前缀索引等都是二级索引。

主键自增对聚簇索引的好处

(摘自:https://www.jianshu.com/p/54c6d5db4fe6,仅作个人备份,浏览请看原文)

对于聚簇索引的存储引擎,数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。它只需要一页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。

由于主键的值是顺序的,InnoDB把每一条记录都存储在上一条记录的后面。当达到页的最大填充因子时(InnoDB默认的最大填充因子是页大小的15/16,留出的部分空间用于以后修改),下一条记录就会写入新的页中。一旦数据按照这样顺序的方式加载,主键页就会近似于被顺序的记录填满,这也是所期望的结果。

人无完人,总结顺序主键缺点:

对于高并发工作负载,在InnoDB中按主键顺序插入可能会造成明显的争用。主键的上界会成为“热点”。因为所有的插入都发生在这里,所以并发插入可能导致间隙锁竞争。另一个热点可能是auto_increment锁机制;如果遇到这个问题,则可能需要考虑重新设计表或者应用,比如应用层面生成单调递增的主键ID,插表不使用auto_increment机制,或者更改innodb_autonc_lock_mode配置。

主键随机对聚簇索引的坏处

如果主键不是自增id,可以想象,它会干些什么,不断地调整数据的物理地址、分页,当然也有其他一些措施来减少这些操作。

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

而当采用UUID的聚簇索引的表往插入数据,如图10所示,因为新行的主键值不一定比之前的插入值大,所以InnoDB无法简单的总是把新行插入到索引的最后,而是需要为新的行寻找合适的位置----通常是已有数据的中间位置----并且分配空间。这会增加很多额外的工作,并导致数据分布不够优化。

总结使用UUID作为主键的一些缺点:

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

把这些随机值载入到聚簇索引以后,需要做一次optimize table来重建表并优化页的填充。

你可能感兴趣的:(数据库)