聚簇索引
-
介绍
聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。InnoDB的聚簇索引实际上是通过一个结构中保存了B-Tree索引和数据行。因为无法同时把数据行存在两个不同的地方,所以一个表只能有一个聚簇索引(覆盖索引可以模拟多个聚簇索引的情况)
-
索引的建立
一个表有且只有一个聚簇索引;
InnoDB一般是通过主键建立聚簇索引;
如果没有定义主键,InnoDB会选择一个唯一的非空索引代替;
如果没有这样的索引,InnoDB会隐式定义一个主键来作为局促索引;
InnoDB只聚集在同一页面中的记录,包含相邻键值的页面可能会相距甚远;
-
优点
1.可以把相关数据保存在一起,减少I/O操作;
2.数据访问更快。找到索引即找到数据;
3.使用覆盖索引扫描的查询可以直接使用叶节点的主键值;
-
缺点
1.插入速度严重依赖插入顺序。按主键顺序插入是加载数据到InnoDB表中最快的方式。如果不是按照主键顺序加载数据,那么在加载完成后最好使用OPTIMIZE TABLE命令重新组织一下表;
2.更新聚簇索引列的代价很高,因为会强制InnoDB将每个被更新的列移动到新的位置;
3.基于聚簇索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临“页分裂”的问题;
4.聚簇索引可能导致全表扫描变慢,尤其是比较稀疏,或者由于页分裂导致数据存储不连续的情况;
5.二级索引(非聚簇索引)可能比想象的要更大,因为在二级索引的叶子节点包含了引用行的主键列。二级索引访问需要两次索引查找。
非聚簇索引
-
介绍
也叫辅助索引或二级索引。一个表中可以有多个二级索引,其叶子节点存放的不是一整行数据,而是键值。叶子节点的索引行中,包含了一个指向聚簇索引的指针,从而在聚簇索引树中找到一整行数据。
-
优点
理论上可以有无限多个,不受限制。当然大家都知道,实际中并不是索引越多越好
-
缺点
非聚簇索引总是要进行二次查询,增加I/O操作
联合索引
-
介绍
包含多个字段的索引。当不需要考虑排序和分组时,将选择性最高的列放在前面同时是比较推荐的;
选择性高是指:某列数据的散列性强,即重复值少。
-
优点
减少索引的建立和维护成本,符合最左匹配原则,参考最左匹配实测
覆盖索引
-
介绍
判断标准:使用explain,可以通过输出的extra列来判断,对于一个索引覆盖查询,显示为using index,MySQL查询优化器在执行查询前会决定是否有索引覆盖查询
从辅助索引中就能获取到需要的记录,而不需要查找聚簇索引中的记录。使用覆盖索引的一个好处是因为辅助索引不包括一条记录的整行信息,所以数据量较聚集索引较少,可以减少大量I/O操作
查询联合索引中的某个或某几个字段的时候,where语句最好是根据最左匹配来定义,那么就会出现覆盖索引
select语句中,如果要查询的结果列,都在联合索引的列中,那么一般都会出现覆盖索引,即explain的时候,会出现Using Index
-
注意
1、覆盖索引也并不适用于任意的索引类型,索引必须存储列的值
2、Hash 和full-text索引不存储值,因此MySQL只能使用B-TREE
3、并且不同的存储引擎实现覆盖索引都是不同的
4、并不是所有的存储引擎都支持它们,Memory不支持
5、如果要使用覆盖索引,一定要注意SELECT 列表值取出需要的列,不可以是SELECT *,因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降,不能为了利用覆盖索引而这么做
6:遇到以下情况,执行计划不会选择覆盖查询
select选择的字段中含有不在索引中的字段 ,即索引没有覆盖全部的列。
where条件中不能含有对索引进行like的操作。
总结
聚簇索引:有且只有一个,通常是主键,推荐是id自增主键
非聚簇索引:只能通过聚簇索引,找到对应的整行数据
联合索引:遵循最左匹配原则,字段顺序有一定的经验和讲究
覆盖索引:建立联合索引时,会出现覆盖索引的情况