这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战
什么是聚簇索引
聚簇索引是一种数据存储方式,其特点是索引的叶子节点就是实际的数据行,由于数据行仅会存在于一个地方,因此一个表只能有一个聚簇索引。索引是由存储引擎实现的,对于InnoDB引擎会优先使用主键作为聚簇索引,如果没有定义主键则会选择一个“唯一的非空索引”代替,如果找不到就会隐式定义一个主键作为聚簇索引。
聚簇索引的数据分布如下图所示
聚簇索引的优点:
- 在相关数据在物理层面保存在一起,例如电子邮件表中可以根据使用“用户ID+自增ID”作为唯一索引,建立聚簇索引,将一个用户的邮件数据在物理层面聚集,这样在查询某个用户全部邮件时可以减少磁盘IO。
- 根据聚簇索引访问数据时,由于索引和数据保存在同一个B-Tree中,获取数据比非聚簇索引快。
缺点:
- 聚簇索引的生成速度依赖于数据插入的顺序,按照主键的顺序进行插入时生成的速度最快。
- 可能会出现“页分裂”问题,即当数据必须插入某个已满的列中,存储引擎会将该页拆成两个页,这使得数据的存储时不连续的,占用了更多的磁盘空间并且全表扫描的速度变慢。
InnoDB和MyISAM的聚簇索引
以下面的表为例,列col1
作为主键
create table layout_test (
col1 int not null,
col2 int not null,
PRIMARY KEY(col1),
KEY(col2)
);
如果使用MyISAM存储引擎,数据按照插入顺序存储在磁盘上,如下所示
MyISAM中的主键索引和其他索引没有不同,主键索引就是一个名为PRIMARY
的唯一非空索引,其叶子节点存储的是“行指针”。
如果使用InnoDB存储引擎,由于支持聚簇索引,因此主键的存储和其他索引不同,如下图所示,聚簇索引存储的是整个表,而不是像MyISAM一样独立的行存储。另外InnoDB的二级索引和MyISAM不同,存储的是“主键值”而不是行指针。
下图展示了InnoDB和MyISAM对主键索引和二级索引处理的区别 InnoDB引擎:主键索引的叶子节点就是数据行,二级索引的叶子节点是主键值 MyISAM引擎:主键索引和二级索引的叶子几点都指向行指针
使用自增主键作为聚簇索引
使用InnoDB引擎最好使用AUTO_INCREMENT
作为主键,保证数据行按顺序写入,避免随机聚簇索引,如使用UUID
作为索引会导致性能下降
UUID
作为主键会使得聚簇索引的插入完全随机,数据没有任何聚集性UUID
的字段长,占用的空间更大- 写入是乱序的使得频繁出现页分裂操作,使得页变的稀疏,占用空间更大