MySql 索引部分 - litter-fish/ReadSource GitHub Wiki

索引类型

B-Tree索引 B-Tree的值都是按照顺序存储的,即查询时候能够加快访问速度,因为不需要进行全表扫描。 所以该索引很适合进行查询范围数据。 B-Tree索引适合:全键值,键值范围或键前缀的查询。 全值查找,匹配最左前缀,匹配列前缀,匹配范围值,精确匹配某一列并范围匹配另外一列,只访问索引的查询(覆盖索引)。

B-Tree索引的限制

  • 如果不是按照索引的最左列开始查找,则无法使用索引。
  • 不能跳过索引中的列。
  • 如果查询中有某个列的范围查找,则其右边的所有列都无法使用索引优化查询。

哈希索引 哈希索引是基于哈希实现的,只有精确匹配索引的所有列的查询才有效。

哈希索引的限制:

  • 哈希索引只包含哈希值和指针,而不能存储字段值。所以不能使用索引中的值来避免读取行。
  • 哈希索引数据不是按照索引值顺序存储的,所以无法用于排序。
  • 不支持部分列查找
  • 哈希索引只支持等值查找,包括=, IN(), <=>
  • 如果哈希冲突很多的话,一些索引的维护代价很高。

InnoDB的自适应哈希索引,当InnoDB注意到某些索引被使用的非常频繁时,存储引擎会在内存中基于B-Tree索引之上再创建一个哈希索引。

索引的优点

  • 索引可以大大减少服务器需要扫描的数量
  • 索引可以帮助服务器避免排序和临时表
  • 索引可以将随机IO变成顺序IO

高性能的索引策略

  1. 独立的列,索引列不能是表达式的一部分,也不能是函数的参数。
  2. 前缀索引和索引选择
  3. 多列索引,
  4. 选择合适的索引列顺序,当不需要考虑排序和分组的时候,将选择性最高的列放在最前面,然而,性能不只依赖于所有索引列的选择性,也和查询条件的具体值有关,即和值的集体分布有关。
  5. 聚簇索引,表示数据行和相邻的键值紧凑的存储在一起 聚簇索引的存储

优点:

  • 可以把相关数据存储在一起
  • 数据访问更快
  • 使用覆盖索引扫描的查询可以直接使用叶节点中的主键值。

缺点:

MyISAM存储引擎索引数据分布 主键和非主键的分布都是一样的 MyISAM存储引擎索引数据分布

INNODN存储引擎数据分布 主键(聚簇索引)的分布: 主键(聚簇索引)的分布

非聚簇索引的分布: 非聚簇索引的分布

  1. 覆盖索引,一个索引包含所有需要查询的字段值,MySql只能使用B-Tree做覆盖索引。 延迟关联的优化方式

索引条件下推(Index Condition pushdown) 存储引擎在访问索引的时候检查筛选字段在索引中的where条件,如果索引元组中的数据不满足推送的索引条件,那么就过滤掉该条记录。 优化器没有使用ICP时:

  1. 当storage engine 读取下一行时,首先读取索引元组,然后使用索引元组在基表中定位和读取整行数据。
  2. server层评估where条件,如果该行数据满足where条件则使用,否则丢弃。
  3. 执行步骤1,直到读取最后一行数据。 索引下切

使用ICP:

  1. storage engine 从索引中读取下一条索引元组
  2. storage engine 使用索引元组评估下推的索引条件,如果没有满足where条件,storage engine 将会处理下一条索引元组。 只有当索引元组满足下推的索引条件的时候,才会继续取基表中读取数据。
  3. 如果满足下推的索引条件,storage engine 通过索引元组定位基表的行和读取行数据并返回给server。 索引下切

使用条件:

  • 只能用于非聚簇索引
  • explain 执行计划中type值为range,ref,req_ref或者ref_or_null。且查询需要访问表的整行数据,即不能使用覆盖索引。

查询性能优化