二刷MySQL高性能——索引相关

849 阅读5分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

前言

上个月底出去面试一波,被锤了一顿,回来重新复习,把用来压泡面的大红书——MySQL高性能又拿出来看了一遍,之前的时候只是通读了一遍,这次主要是选择性的读,主要集中在第五和第六章(多了实在记不住),今天这篇文章就来总结一下,MySQL高性能里面的第五章——高性能的索引

什么是索引

先一步步来,先来了解一下什么是索引,其实索引本质上来说,有点类似于我们书本里书的目录,它可以方便我们在查找书本对应内容的时候,可以快速的定位到内容的位置。

在MySQL里面大致上可以分为两种比较常见的索引类型,一种是Btree索引,另一种是哈希索引,但需要注意的是,因为对于新版的MySQL来说,默认的存储引擎是InnoDB存储引擎,而在InnoDB存储引擎里面,对于哈希索引的使用是自适应的,也就是说哈希索引不是人为的去创建,而是由存储引擎去决定什么时候使用。

初探Btree索引

Btree索引可以加快数据访问的速度,那是因为有了Btree索引之后,再想找到某一条数据就不再需要使用全表扫描了,而是可以通过Btree索引的根结点来进行搜索。

通过比较节点页的值和要查找的值可以找到合适的指针,最终进入下一层的节点,最终存储引擎要么可以找到该值,要么就是没有这条记录。

在Btree索引里面,它是存在顺序的,所以在使用的时候,它可以被用来做范围的查询。

例如下面的这个例子,我们在pro_id上面建立一个索引

CREATE INDEX pro_index ON snapProduct(pro_id);

当我们在后续不管是对pro_id进行精确查找还是说范围查找,它都可以用到索引

EXPLAIN SELECT * FROM snapProduct WHERE pro_id > 2;

1623744488430.jpg

在查询中,要想使用Btree索引,则必须满足下面条件中的一条

  1. 全值匹配 全值匹配的意思也就是在查询过程中,直接通过=‘xxx’的方式来进行查询,例如索引列是name,查询方式
SELECT name, age FROM snapProduct WHERE name = 'test';

这样的查询方式是可以使用到索引的

  1. 匹配左前缀 我们在创建索引的时候,除了有普通的单列索引,还可以创建联合索引,这时候要想使用到这个联合索引,则查询的条件必须满足最左前缀,也就是建立的索引为
CREATE INDEX pro_type_index ON snapProduct(pro_id,type);

那么在查询的过程中,则必须是

SELECT name FROM snapProduct WHERE pro_id = 10 AND name = 'test';
  1. 匹配列前缀

在索引匹配的过程中,例如匹配User表里面的name列中的J开头的名字,这样就是所谓的匹配列前缀。

  1. 匹配范围值

匹配范围值,顾名思义就是在查询的过程中进行范围性的匹配,这样也是可以使用到索引的,例如

SELECT score FROM `imc_classvalue` WHERE user_id > 10 AND user_id < 100;

但是需要注意的是,当第一列查询使用了范围查询的时候,后面的筛选语句就无法再使用索引了。

例如

SELECT score FROM `imc_classvalue` WHERE user_id > 10 AND user_id < 100 AND level_score = 9.1;

这样的查询对于level_score是无法使用到该列上的索引的。

  1. 精确匹配一列,范围匹配另一列

同上面一个同样的道理,如果精确匹配和范围查询两个相互调转顺序,则又可以使用到两个列上的索引了。

  1. 只访问索引的查询

这种查询也就是常说的覆盖索引,也就是列的内容是被索引给覆盖到的,也就是再查询的过程中,只需要访问索引的值,就可以读取到这次需要查询的列的内容,则再这种也可以使用过到索引来进行查询。

哈希索引

在Mysql中还有另外一种索引类型,就是哈希索引,这种索引对于现在的Mysql的Innodb存储引擎来说,它是属于自适应的创建,而不是由我们人为的去创建,也就是存储引擎认为你需要使用到哈希索引的时候,它才会被创建出来。 这种一般我们不需要我们管的,这里就不做过多的讨论。

索引的优点

索引其实就有点类似于书本里的目录,可以让我们快速的定位到所要寻找的内容位置,总结起来的话,索引的优点有三个:

1. 索引大大的减少了服务器需要扫描的数据行。

2. 索引帮助服务器避免排序和临时表。

3. 所i你可以将随机I/O变成顺寻I/O。

索引是最好的解决方案吗

其实很多时候,对于一个数据量不大的小表来说,采用全表扫描的方法,可能要比用索引去搜索,速度要更快,对于中大型的表来说,采用索引则会大大加快搜索的一个效率,可是当表变成特大号的时候,不管是建立还是使用索引,所带来的性能消耗都是巨大的,这种情况下就需要用到另一个种解决手段了。

最后

今天的任务完成,让我们下期再见,拜拜

image.png