MySQL优化-03索引

索引

一.索引的作用

  1. 一个索引就是一颗B+树,索引让我们可以快速定位和扫描到我们想要的数据,增加查询速度。
  2. 在一个select查询语句中最多用到一个二级索引,即使在where条件中使用了多个二级索引。

二.InnoDB存储引擎支持的索引

B+树索引、哈希索引、全文索引,其中最重要的是B+树索引,它是mysql最常用的索引。

三.B+树索引

1.聚簇索引/聚集索引

  1. 它是一种主键索引,MySql 会通过主键生成一颗B+树,B+树的叶子节点中存储的是整行数据。
  2. 如果没有主键,MySql会通过rowId来生成B+树。

2.辅助索引/二级索引

  1. 它是Mysql由索引列生成的一颗B+树,B+树的叶子节点存储内容不包行记录的全部数据,它存储除了包含键值以外,还包含一个书签来存储主键。
  2. 每定义一个二级索引就会生成一颗B+树。
  3. 如果查询的内容不是索引列也不是主键列,那么会进行回表操作,所谓回表就是通过二级索引找到叶子节点,再拿叶子节点的主键去主键索引中查找内容,比较耗时,因此应该尽量少的避免回表操作。

3.联合索引/复合索引

  1. 它是由多列组成的索引,MySql通过联合索引生成一颗B+树,它的叶子节点存储的是作为联合索引的列数据+主键。
  2. B+树遵循最左侧优先排原则,所谓最左侧优先排原则就是B+会根据从左到右的列进行排序。

4.覆盖索引

  1. 如果从辅助索引中可以查询到的记录,而不需要查询聚簇索引中的记录,从而避免回表操作。
  2. 它不是索引类型的一种。

举个例子:表student中有id,name,age,desc四个列,创建一个name+age的联合索引;

  1. select name from student where age = ‘18’,使用了覆盖索引,可以直接从联合索引中取到name;
  2. select name,desc from student where age = ‘18’,没有使用覆盖索引,因为desc列需要回表操作,从聚簇索引中取数据;

四.自适应Hash索引

  1. 决定B+树索引的效率是树的高度,MySql一般B+树的高度一般为34层,那么就需要34此的IO操作来查询数据。因此,Mysql提供了Hash索引。
  2. 对于热数据来说,使用B+树索引效率慢。
  3. MySql监控会对热数据创建Hash索引,只需要一次操作就可以查询到数据,底层是除法散列表。
  4. 它的缺点是无法排序。
  5. MySql5.7开始,自动开启自适应Hash索引。SHOW ENGINE INNODB STATUS 命令查看Hash索引

五.高性能索引创建策略

索引列的类型尽量小(主键)

  1. 这个条件只针对主键来讲。
  2. 因为二级索引、联合索引都要存储主键列,索引索引越小,占用的空间越小,同样的内存空间存储的数据行数越多,IO操作越少,同时cup执行越快。

索引列离散型高

  1. 索引列的离散型越高,索引效率越高,离散型=不重复索引值的/表记录总数。
  2. 使用 select count(distinct 列)/count(*) from table可以计算离散型。越接近1越适合做索引。

前缀索引

  1. 对于字段比较长的列,比如blob、text、很长的varchar,mysql不支持索引她们的全部长度,可建立前缀索引。
  2. 语句:alert table 表名 add key/index (column(x)),x表示前缀长度。
  3. 使用select count(distinct left(列名,长度x))/count(*) from table确定x的合适值。
  4. 它不支持group by 和 order by,也无法覆盖索引,因为要回表。

后缀索引

mysql不支持后缀索引,可以增加一个列将后缀倒排放到列中,给新增的列加索引。使用场景:邮箱后缀。

以上三个都是对于单个索引的创建策略

多列索引

  1. 多列索引的创建一般要根据不同的业务场景来创建。
  2. 一般来讲:
    1. 将离散型高的列放到索引前面。
    2. 根据运行频率最高的查询来调整索引列。
    3. 性能优化时,需要相同的列,不同的顺序来创建索引。比如order a,b,c 和order c,b,a来创建两个列相同但顺序不同的索引。

三星索引

满足条件:

  1. 索引的选择性:索引的字段能够显著减少查询结果集的大小,即索引字段的唯一值越多,能够过滤掉的数据越多,从而获得一颗星。
  2. 排序和分组性能:如果索引的列排序顺序能够匹配查询语句中的ORDER BY或GROUP BY的顺序,这样的索引可以被评定为两颗星。这允许查询直接利用索引完成排序或分组,避免了额外的排序操作。
  3. 覆盖索引:如果索引包含了查询语句中所有的列,那么这个索引就是一个覆盖索引,会被评定为三颗星。这意味着查询可以仅通过访问索引获取所有需要的信息,无需访问实际的数据表,从而大大提高查询效率。

综上所述,三星索引是指在选择性、排序和分组性能以及覆盖索引三个方面都达到最优的索引。这种索引能够最小化必须扫描的索引片宽度,避免排序操作,以及避免回表操作,从而极大地提升查询效率。然而,三星索引也有其缺点,比如在小型表和超大型表上的效果可能不佳,因为小型表的全表扫描代价很小,而超大型表的索引维护成本很高。

六.高性能索引使用策略

1. 不在索引上做任何操作

不要在索引列上做任何操作,如计算、函数、(自动/手动)类型转换等,这些操作都会导致索引失效而转向全表扫描。

2. 全值匹配法则

搜索条件和索引列相同,顺序没有影响,因为查询优化器存在。

3. 最佳左前缀法则

在使用复合索引时,查询的过滤条件必须从索引的最左边开始,并且不能跳过中间的列。

5. 覆盖索引尽量用

减少回表操作。

6. 索引的否定条件

在使用不等于 !=、<> 的时候无法使用索引会导致全表扫描;IN 走索引(多值精确匹配),NOT IN 索引失效,导致全表扫描;

7. 字符串加引号

如果使用数字类型相当于在索引列上做操作,导致索引失效。

8. OR关键字使用UNION替换

用 OR 分割开的条件, 如果 OR 前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。所以,对于包含 OR 的查询子句,如果要利用索引,则 OR 之间的每个条件列都必须用到索引,而且不能使用到复合索引;如果没有索引,则应该考虑增加索引。

9. 范围条件放最后

  1. 左边列是精确查找,则右边列可进行范围查找
  2. 中间有范围查找会导致后面列全部失效,无法充分利用联合索引

10.is null 和 is not null

  1. sql1: select * from emp where id is null;
  2. sql2: select * from emp where id is not null;
  3. 如果id可为空sql1会走索引,如果不可为空where条件没用;
  4. 无论id是否可以为空,都走全表扫描

11.like模糊查询

尽量%放到后面,放前面索引失效;覆盖索引可解决此问题

12.排序

尽量要用B+树中的顺序一致;

13.尽量使用主键顺序插入行

比如自增ID,插入数据就直接往后面插就可以了,而uuid会往B+树中间插数据;

14.limit优化

  1. 自身表关联查询用ID主键;
  2. where用ID过滤比如 where id > xxx;
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值