MySQL索引总结(2)——聚簇索引与非聚簇索引
1、聚集索引
表数据按照索引的顺序来存储的,也就是说索引项的顺序与表中记录的物理顺序一致。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。
在一张表上最多只能创建一个聚集索引,因为真实数据的物理顺序只能有一种。
从物理文件也可以看出 InnoDB(聚集索引)的数据文件只有数据结构文件.frm和数据文件.idb 其中.idb中存放的是数据和索引信息 是存放在一起的。
2、非聚集索引
表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,其行数量与数据表行数据量一致。
从物理文件中也可以看出 MyISAM(非聚集索引)的索引文件.MYI和数据文件.MYD是分开存储的 是相对独立的
总结:
聚簇索引和非聚簇索引的区别是:
聚簇索引(innoDB)的叶子节点就是数据节点;
而非聚簇索引(myisam)的叶子节点仍然是索引文件 只是这个索引文件中包含指向对应数据块的指针
对于 非聚簇索引 来说,每次通过索引检索到所需行号后,还需要通过叶子上的磁盘地址去磁盘内取数据(回行)消耗时间。为了优化这部分回行取数据时间,InnoDB 引擎采用了聚簇索引。
聚簇索引,即将数据存入索引叶子页面上。对于 InnoDB 引擎来说,叶子页面不再存该行对应的地址,而是直接存储数据。
这样便避免了回行操作所带来的时间消耗。 使得 InnoDB 在某些查询上比 MyISAM 还要快!
ps. 关于查询时间,一般认为 MyISAM 牺牲了功能换取了性能,查询更快。但事实并不一定如此。多数情况下,MyISAM 确实比 InnoDB 查的快 。但是查询时间受多方面因素影响。InnoDB 查询变慢得原因是因为支持事务、回滚等等,使得 InnoDB的叶子页面实际上还包含有事务id(换句话说就是版本号) 以及回滚指针。
动作描述 | 使用聚集索引 | 使用非聚集索引 |
列经常被分组排序 | 使用 | 使用 |
返回某范围内的数据 | 使用 | 不使用 |
一个或极少不同值 | 不使用 | 不使用 |
小数目的不同值 | 使用 | 不使用 |
大数目的不同值 | 不使用 | 使用 |
频繁更新的列 | 不使用 | 使用 |
外键列 | 使用 | 使用 |
主键列 | 使用 | 使用 |
频繁修改索引列 | 不使用 | 使用 |
简单来说,聚簇索引不适用于频繁更新的列、频繁修改的索引列和小数目的不同值。