转自:mysql索引之聚集索引
聚集索引不是一种单独的索引类型,而是一种存储数据方式。其具体细节依赖于实现方式,但是InnoDB的聚集索引实际上在同样的结构中保存了B-Tree索引和数据行。
当表有聚集索引的时候,它的数据行实际保存在索引的叶子页中。术语“聚集”指实际的数据行和相关的键值都保存在一起。每个表只能有一个聚集索引,因为不能一次把行保存在两个地方。(但是,覆盖索引可以模拟多个聚集索引)
当前,SolidDB和InnoDB是唯一支持聚集索引的存储引擎。InnoDB按照主键进行聚集,如果没有定义主键,InnoDB会试着使用唯一的非空索引来代替。如果没有这种索引,InnoDB就会定义隐藏的主键然后在上面进行聚集。
聚集主键有助于性能,但是它也能导致严重的性能问题。
优点:
1.可以把相关数据保存在一起。
2.数据访问快。聚集索引把索引和数据都保存到同一棵B-Tree中,因此从聚集索引中取得数据通常在非聚集索引进行查找要快。
3.使用覆盖索引的查询可以使用包含在叶子节点中的主键值
如果表和查询可以使用它们,这些优点能极大地提高性能。
缺点:
1.聚集能最大限度地提升I/O密集负载的性能。如果数据能装入内存,那么其顺序也就无怕谓了,这样聚集就没什么用处。
2.插入速度严重依赖于插入顺序。按照主键的顺序插入行是把数据装入InnoDB表最快的方法。如果没有按照主键顺序插入数据,那么在插入之后最好使用OPTIMIZE TABLE重新组织一下表。
3.更新聚集索引列是昂贵的,因为它强制InnoDB把每个更新的迁移到新的位置。
3.建立在聚集索引上的表在插入新行,或者在行的主键被更新,该行必须被移动的时候会进行分页。分布发生在行的键值要求行必须被放到一个已经放满了数据的页的时候,此时存储引擎必须分页才能容纳该行。分页会导致表占用更多的磁盘空间
4.聚集表可能会比全表扫描慢,尤其在表存储得比较稀疏或因为分页而没有顺序存储的时候。
5.第二(非聚集)索引可能会比预想的大,因为它们的叶子节点包含了被引用行的主键列。
6.第二索引访问需要两次索引查找,而不是一次(叶子节点不会保存引用的行的物理位置,而是保持了行的主键值)
这意味着为了从第二索引查找行,存储引擎首先要找到叶子,然后使用保存在那里的主键值找到主键。最终找到行。这需要两次动作,两次B-Tree导航(在InnoDB中,自适应哈希索引能减少这种损失)
如果正在使用InnoDB并且不需要任何特定的聚集,就可以定义一个代理键。它是一种主键,但是值和应用程序无关。最简单的方法是使用AUTO_INCREMENT列。这会是顺序插入的并且能提高使用主键联接的性能,减少分页和碎片产生。
另外请参考:聚集索引与非聚集索引