MySQL聚集索引和非聚集索引

MySQL聚集索引和非聚集索引

聚集索引

概念理解

聚集索引中键值的逻辑顺序决定了数据表的物理顺序,即聚集索引的键值对的顺序与数据表中数据的顺序是一致的。所以每一张数据表,只能有一个聚集索引
一般来说MySQL中,聚集索引会自动选择主键列。其他情况稍后解释。
除了MyISAM引擎其他引擎中,索引的叶子节点就是对应的数据节点。可以直接获取到对应的全部列的数据。而非聚集索引则需要二次查询。
注意:聚集索引可以是联合索引。

聚集索引自动创建规则

InnoDB聚集索引的叶子节点存储行记录,因此InnoDB必须要有且只有一个聚集索引。

  • 如果表定义了PK(Primary Key,主键),那么PK就是聚集索引。
  • 如果表没有定义PK,则第一个NOT NULL UNIQUE的列就是聚集索引。
  • 否则InnoDB会另外创建一个隐藏的ROWID作为聚集索引。

这种机制使得基于PK的查询速度非常快,因为直接定位的行记录。

优点

  • 由于聚集索引的逻辑顺序与数据表的物理顺序一致,且聚集索引将索引和数据保存在同一个btree中(MyISAM除外,MyISAM的B+Tree的叶子节点上的data,并不是数据本身,而是数据存放的地址,聚集索引和非聚集索引没啥区别,只是聚集索引中的key一定得是唯一的),所以可以大大提高查询效率。
  • 同时如果是按照聚集索引的顺序来做排序查询,那么排序效率更加凸显。
  • 使用索引覆盖查询可以直接使用页节点中的主键值。

缺点

  • 聚集数据最大限度地提高了IO密集型应用的性能,但如果数据全部放在内存中,则访问的顺序就没有那么重要了,聚集索引也没有什么优势了。
  • 插入速度严重依赖于插入顺序,按照主键的顺序插入是加载数据到innodb表中速度最快的方式,但如果不是按照主键顺序加载数据,那么在加载完成后最好使用optimize table命令重新组织一下表。
  • 更新聚集索引列的顺序的代价很高,因为会强制innodb将每个被更新的行移动到新的位置。
  • 聚集索引可能导致全表扫描变慢,尤其是行比较稀疏,或者由于页分裂导致数据存储不连续的时候。

非聚集索引

概念理解

非聚集索引简单理解就是我们自己手动创建的索引。非聚集索引的顺序与数据表的顺序没有任何联系。只是在btree的叶子节点存储着该行数据的PK(即Id)。所以非聚集索引在找到该行数据的PK后,需要回表查询。简单解释即根据数据行的PK回到聚集索引中找到该行数据。所以需要扫描两遍树。性能相对于只扫描一遍的聚集索引效率较低。当然可以通过索引覆盖查询一定程度解决这个问题。具体怎么解决之后再开一篇笔记记录。

总结

  • 聚集索引的查询效率比非聚集索引高的多。
  • 频繁修改聚集索引的值,写入效率并不高。因为需要移动对应数据的物理位置。
  • 聚集索引不会进行回表查询,因为btree的叶子节点就是存储着这行数据的实际内容。
  • 非聚集索引在查询的时候通常会引起回表查询。因为btree的叶子节点存储着的是该行数据的PK,需要回到聚集索引通过PK找到具体数据。
  • 非聚集索引也可以通过索引覆盖查询的方式避免回表查询,这样的效率会高很多。

你可能感兴趣的:(mysql,sql,数据库)