简介
- 不是一种单独的索引类型,而是一种数据存储方式
- 一个表只能有一个聚簇索引
- 不是所有引擎都支持
优点
- 同一个结构中保存了B-TREE 索引和数据行,所以是在同一个文件,数据访问更快
- 使用覆盖索引扫描的查询可以直接使用页节点中的主键值。
- 可以把相关数据保存在一起。例如实现电子邮箱时,可以根据用户 ID 来聚集数据,这样只需要从磁盘读取少数的数据页就能获取某个用户的全部邮件。如果没有使用聚簇索引,则每封邮件都可能导致一次磁盘 I/O。
缺点
- 更新聚簇索引代价很大,因为会强制将每个被更新的行移动到新的位置上,且有可能面临“页分裂”问题。(当行的主键值必须将这一行插入某个已满的页中时,存储引擎会将该页分裂成两个页来存储)
- 有可能使全表扫描变慢,尤其是行比较稀疏时,或者是页分裂导致数据存储不连续的时候
- 插入的性能严重依赖插入的顺序,如果是按照主键的顺序插入是最快的方式,因为存储在上一条记录的后面,但如果使用uuid ,新插入的主键值 不一定比之前插入的大,所以需要找到合适的位置,以下说明
- 因为写入是乱序的,InnoDB不得不频繁的做页分裂操作,为新的行分配空间,页分裂会导致移动大量的数据, 一次插入最少需要修改三个页。
- 频繁的页分裂,页会变得稀疏且被不规则地填充,所以数据会有碎片,导致资源的浪费
- InnoDB 插入之前要先找到从磁盘读取目标页到内存中,会导致大量的随机i/o
顺序的主键(自增)的缺点
- 并发插入导致间隙锁竞争
- 业务对外暴露自增id 容易被爬虫、猜解、跨权限泄露数据等(解决方案:可以使用 数字中生成类似YouTube的ID https://github.com/ivanakimov/hashids.php)
数据结构原理
以下 叶子页包含了行的全部数据,但是节点页只包含了索引列。聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一的非空索引代替。如果没有这样的索引,InnoDB 会隐式定义一个主键来作为聚簇索引

性能使用对比 (2018-01-14 更新)
- MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试) , 不过需要回归业务,能使用自增ID来实现的就不要使用UUID,要考虑到分布式的情况下ID的唯一性