基本介绍
聚集索引
聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一个聚集索引,因为一个表的物理顺序只有一种情况,所以,对应的聚集索引只能有一个。
如果某索引不是聚集索引,则表中的行物理顺序与索引顺序不匹配,与非聚集索引相同,聚集索引有着更快的检索速度。
非聚集索引
一种索引,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。
优劣势
优点
- 1.可以把相关数据保存在一起,如:实现电子邮箱时,可以根据用户ID来聚集数据,这样只需要从磁盘读取少量的数据页就能获取某个用户全部邮件,如果没有使用聚集索引,则每封邮件都可能导致一次磁盘IO
- 2.数据访问更快,聚集索引将索引和数据保存在同一个
btree
中,因此从聚集索引中获取数据通常比在非聚集索引中查找要快 - 3.使用覆盖索引扫描的查询可以直接使用页节点中的主键值
缺点
- 1.聚簇数据最大限度地提高了IO密集型应用的性能,但如果数据全部放在内存中,则访问的顺序就没有那么重要了,聚集索引也没有什么优势了
- 2.插入速度严重依赖于插入顺序,按照主键的顺序插入是加载数据到
innodb
表中速度最快的方式,但如果不是按照主键顺序加载数据,那么在加载完成后最好使用1optimize table`命令重新组织一下表 - 3.更新聚集索引列的代价很高,因为会强制
innodb
将每个被更新的行移动到新的位置 - 4.基于聚集索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临页分裂的问题,当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这就是一次页分裂操作,页分裂会导致表占用更多的磁盘空间
innodb
和myisam
物理存储的数据分布对比
myisam
:
是按照数据插入的顺序存储在磁盘上的,myisam
中的主键索引和二级索引在结构上并没有什么不同,主键索引就是一个名为primary
的唯一非空索引。
innodb
:
因为innodb
支持聚集索引,所以使用非常不同的方式存储同样的数据,innodb
聚集索引包含了整个表的数据,而不是只有索引,因为在Innodb
中,聚集索引就是表,所以不像myisam
那样需要独立的行存储。聚集索引的每一个叶子节点都包含了主键值,事务ID,用于事务和MVCC
的回滚指针以及所有剩余列的值,如果主键是一个列前缀索引,innodb
也会包含完整的主键列和剩下的列的值。
还有一点和myisam
不同的是,innodb
的二级索引和聚集索引很不同,innodb
二级索引的叶子节点中存储的不是行指针,而是主键值,并以此作为指向行的指针,这样的策略减少了当出现行移动或者数据页的分裂时二级索引的维护工作,使用主键值当做指针会让二级索引占用更多的空间,换来的好处是,innodb
在移动行时无须更新二级索引中的这个指针。
何时使用聚集索引或非聚集索引
动作描述 | 使用聚集索引 | 使用非聚集索引 |
---|---|---|
列经常被分组排序 | 应 | 应 |
返回某范围内的数据 | 应 | 不应 |
一个或极少不同值 | 不应 | 不应 |
小数目的不同值 | 应 | 不应 |
大数目的不同值 | 不应 | 应 |
频繁更新的列 | 不应 | 应 |
外键列 | 应 | 应 |
主键列 | 应 | 应 |
频繁修改索引列 | 不应 | 应 |
总结:
- 聚集索引就字典的首字母查询
- 非聚集索引就是字典的边盘部首查询
- 聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个
- 聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续