MySQL-索引

3/15/2023 MySQL索引

索引是一种数据结构,帮助SQL高效获取数据的。类似一本书的目录,可以快速对特定值进行定位和查找,从而大大加快数据查询的效率。

# 索引优缺点

# 索引优点

  • 索引可以大大减少需要扫描的数据量
  • 索引可以避免排序和临时表,索引已经有序
  • 索引可以尽量将随机IO变成顺序IO,例如:聚簇索引包含数据,且索引是有序的,就可以快速获得批量数据,但如果回表,通过主键查询数据,则又变成随机IO
  • 索引对于InnoDB(支持行级锁)非常重要,InnoDB对需要访问的元组加锁,而索引能够减少InnoDB访问的元组数,如果查询不能使用索引,MySQL会进行全表扫描,导致锁住全表。

# 索引缺点

  • 降低了更新表的数据,因为不仅要更新原始数据,还要更新索引
  • 索引占用磁盘空间
  • 数据列如果包含了许多重复的内容,例如性别为:男、女,索引选择可能只筛选一半的数据量,效果不是很好
  • 对于数据量非常小的表,索引意义不大,有时全表扫描更高效

MySQL单张表最多只支持16个索引注意

# 索引类型

# 按功能逻辑划分

# 普通索引

普通索引仅仅加快对数据的访问速度,常用于查询条件(where field_name=value)或排序条件(order by field_name)这些场景中。

# 唯一索引

唯一索引相比较普通索引,要求索引列的值必须唯一,但允许有空值。

# 主键索引

主键索引是一种特殊的索引,不允许有空值,一张表只能有一个主键,一般在建表的时候通过primary key(field_name)指定

# 全文索引

mysql Like '%xxx'就会导致索引失效,为了模糊搜索需求,例如:like '%hello%',就需要全文索引支持。InnoDB在5.6版本之后支持全文索引。

# 按物理逻辑划分

# 聚簇索引

聚簇索引的叶子节点直接存储数据,因此查询的时候只需要进行一次查询

# 非聚簇索引

非聚簇索引的叶子节点存储数据的主键,因此查询的时候需要进行两次查询:先查询聚簇索引获取到主键,再通过主键查询数据。

# 按字段个数划分

# 单一索引

索引只使用一个字段

# 联合索引

索引使用多个字段 例如:

alert table user add index index_name_city_age(name,city,age)
1

MySQL联合索引遵从:最左匹配原则

上面索引相当于建立下面三组索引:

  • name,city,age
  • name,city
  • name

因此:

  • 如果查询条件是:(city)、(city,age)、(age)都不会命中索引
  • 如果查询条件是:(name,age),则会命中name索引

理论上最左匹配原则中索引对 where 中子句的顺序也是敏感的,但是由于MySQL的查询优化器会自动调整 where 子句的条件顺序以使用适合的索引,所以实际上 where 子句顺序不影响索引的效果。

如果联合索引有范围查询,就会停止匹配

如果分别在 x, y, z 上建立单列索引,让该表有3个单列索引,索引效率也会大不一样,在联合索引生效的情况下,单个索引的效率远远低于联合索引。这是由 MySQL 查询优化器的执行顺序决定的,在执行一条查询 sql 时,针对索引的选择大致有如下步骤:

MySQL 优化器根据搜索条件,找出所有可能使用的索引 计算全表扫描的代价 计算使用不同索引执行查询的代价 对比各种执行方案的代价,找出成本最低的那一个 因此,虽然有多个单列索引,但 MySQL 只能用到其中的那个系统认为似乎是最有效率的,其他的就会失效。

# 总结

# 索引推荐使用情况

  • WHERE, GROUP BY, ORDER BY 子句中的字段
  • 多个单列索引在多条件查询是只会有一个最优的索引生效,因此多条件查询中最好创建联合索引。
  • 联合索引的时候必须满足最左匹配原则,并且最好考虑到 sql 语句的执行顺序,比如 WHERE a = 1 GROUP BY b ORDER BY c, 那么联合索引应该设计为 (a,b,c),因为mysql 查询语句的执行顺序 WHERE > GROUP BY > ORDER BY。参见
  • 多张表 JOIN 的时候,对表连接字段创建索引。
  • 当 SELECT 中有不在索引中的字段时,会先通过索引查询出满足条件的主键值,然后通过主键回表查询出所有的 SELECT 中的字段,影响查询效率。因此如果 SELECT 中的内容很少,为了避免回表,可以把 SELECT 中的字段都加到联合索引中,这也就是宽索引的概念。但是需要注意,如果索引字段过多,存储和维护索引的成本也会增加。

# 不推荐使用或索引失效情况

  • 数据量很小的表
  • 有大量重复数据的字段
  • 频繁更新的字段
  • 如果对索引字段使用了函数或者表达式计算,索引失效
  • 字段类型不一致也会失效,因为等价使用函数
  • innodb OR 条件没有对所有条件创建索引,索引失效
  • 大于小于条件 < >,索引是否生效取决于命中的数量比例,如果命中数量很多,索引生效,命中数量很小,索引失效
  • 不等于条件 !=、<>,索引失效
  • LIKE 值以 % 开头,索引失效
最近更新时间: 7/26/2023, 6:37:16 AM
什么鸟日子
蒙太奇