索引类型
从物理存储角度:
聚集索引
InnoDB 叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有)
非聚集索引
索引的逻辑顺序与磁盘上的物理存储顺序不同。非聚集索引的键值在逻辑上也是连续的,但是表中的数据在存储介质上的物理顺序是不一致的,即记录的逻辑顺序和实际存储的物理顺序没有任何联系。索引的记录节点有一个数据指针指向真正的数据存储位置。
从数据结构角度:
B-Tree索引
B-Tree索引,实际上很多存储引擎使用的是B+Tree,即每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。InnoDB使用的是B+Tree.
B-Tree索引限制:
1 如果不是按照索引的最左列开始查找,则无法使用索引。
2 不能跳过索引中的列。
3 如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。
全文索引
全文索引更类似于搜索引擎做的事情 ,而不是简单的where条件匹配,在相同的列上同时创建全文索引和基于值的B-Tree索引不会有冲突,全文索引适用于MATCH AGAINST操作,而不是普通的WHERE操作。
哈希索引
基于哈希表实现,只有精确匹配所有列的查询才有效。
空间数据索引(R-Tree)
从逻辑角度:
覆盖索引
如果一个索引包含所有需要查询的字段的值,那么我们就称之为“覆盖索引”,由于InnoDB的聚集索引,覆盖索引对InnoDB表特别有用。InnoDB的二级索引在叶子节点保存了行的主键值,所以如果二级主键能够覆盖查询,则可以避免对主键索引的二次查询。MySQL只能使用B-Tree索引做覆盖索引。如果在查询计划EXPLAIN中出现了“Using index”,就出现了覆盖索引。
二级索引
- 表中的聚簇索引(clustered index )就是一级索引,除此之外,表上的其他非聚簇索引都是二级索引,又叫辅助索引(secondary indexes)。
- InnoDB的主键采用聚簇索引存储,使用的是B+Tree作为索引结构,但是叶子节点存储的是索引值和数据本身(注意和MyISAM的不同)。
- InnoDB的二级索引不使用聚蔟索引,叶子节点存储的是KEY字段加主键值。因此,通过二级索引查询首先查到是主键值,然后InnoDB再根据查到的主键值通过主键索引找到相应的数据块。
索引优点
- 索引大大减少了服务器需要扫描的数据量
- 索引可以帮助服务器避免排序和临时表
- 索引可以将随机IO变为顺序IO.
- 如果表数量特别多,可以建立一个元数据信息表,用于记录哪个用户的信息存储在哪个表中。
具体策略
条件过滤
- 如果MySQL使用某个索引进行范围查询,也就无法再使用另一个进行排序了
- 尽可能将需要做范围查询的列放到索引的后面,以便优化器能使用尽可能多的索引列。
- Extra列出现 了“Using where”,表示MySQL服务器将存储引擎返回行以后再应用where 过滤条件。
- 如果不能使用索引查找和锁定行的话,MySQL会做全表扫描。
冗余和重复索引
重复索引是指在相同的列上按照相同的顺序创建的相同类型的索引。大多数情况下都不需要冗余索引,应该尽量扩展已有的索引而不是创建新索引
索引排序
只有当索引的列顺序和ORDER BY 子名的顺序完全一致,并且所有列的排序方向(倒序或正序)都一样时,MySQL才能够使用索引来对结果做排序。如果查询需要关联多张表,则只有当ORDER BY 子句引用的字段全部为第一个表时,才能使用索引做排序。
多列索引
- 在多个列上建立独立的单列索引大部分情况下并不能提高MySQL的查询性能。
- 当服务器对多个索引做相交操作时(通常有多个AND条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引。
其他
- 独立的列:是指索引不能是表达式的一部分,或者函数的参数。
- 选择合适的索引列顺序。
- 前缀的“基数”应该接近于完整列的“基数”
- MySQL不能在索引中执行LIKE操作,这是底层存储引擎API的限制,但能在索引中做最左前缀匹配的LIKE比较,但如果是通配符开关的LIKE查询,就无法比较。