MySQL优化相关的名词以及一些简单的优化

写在开头

本文章适合了解mysql索引以及B+树的朋友观看

基础知识

  • 1.一次IO,可以加载一个node(索引树的一个节点),具体可以参考这篇文章
  • 2.mysql每次IO,读取的大小默认为16k,该值可以修改
  • 3.当我们创建表时没有设置主键,mysql会选一列(该列的值为“唯一”)作为主键列,如果不存在“唯一列”,mysql会自动生成row_id列做主键。并且会根据该主键生成主键索引
  • 4.只有主键索引的叶子节点保存了具体的行数据,普通索引的叶子节点保存的是id值。通过普通索引获取到id值后再经过主键索引查询到具体数据这一过程称之为“回表”
  • 5.聚簇索引(主键索引):是一种数据的存储结构,指所有完整的用户记录都存放在这个聚簇索引的叶子节点处
  • 6.一个表只能有一个聚簇索引(主键索引)

什么是回表

假设我现在有一个teacher表,主键为id,并且单独为name建立了一个索引


image.png

那么这张表的主键索引数据结构如下:


image.png

当我执行select * from teacher wehre id = 1的查询过程

  • 1.where 后面跟的是id,有存在id的索引,根据索引进行查询
  • 2.进行一次IO操作,将最B+树最顶部节点的索引数据读取到内存中
    1. 比对发现1<3,走左1指针
    1. 进行一次IO操作,将左一节点数据加载到内存
  • 5.比对并找到id=1,返回数据(1,周老师)

teacher表name索引的数据结构如下,下图只是模拟了一下,排序是错误的:

image.png

可以看到普通索引name的索引图中,叶子节点并不保存具体的行数据,只是保存了id
当我们执行select * from teacher where name="李老师”,通过name索引获取到的是一个id,如果要得到具体的行数据,还得通过id去主键索引中查询,这个过程就叫回表

回表带来的问题

当查询需要进行回表操作时,对磁盘的IO操作会增加,我们都知道磁盘的读写速度远慢于内存,增加的IO操作无疑会增加查询语句执行的时间。

如何避免回表(索引覆盖)

image.png

我们再来看看普通索引的结构图,当我们查询的数据,在普通索的叶子节点就能获取到时,就不再需要执行回表的操作,也就是当我们执行以下查询语句时,是不需要进行回表操作的

  • select id from teacher where name like "李%"
  • select name from teacher where name like "李%"
  • select id,name from teacher where name like "李%"

需要注意的是select * 是一定会进行回表操作的,所以我们写sql时要避免写select *

上面提到的避免回表操作的方法称之为“索引覆盖”

最左匹配

当我们创建一个组合索引(id,name)时,下面的查询语句时可以使用到该组合索引的?

  1. select id, name from teacher where id=1 and name = "李老师"
  2. select id,name from teacher where id=1
  3. select id,name from teacher where name="李老师"
  4. select id,name from teacher where name="李老师" and id=1

答:
1和2,where后面跟着的查询条件顺序符合最左匹配原则,可以走该组合索引。
4语句会被mysql的优化器优化成1,所以也会走该组合索引

模糊查询是否会走索引

select id from teacher where name like "李%",走name索引

select id from teacher where name like "%李",不走name索引

组合索引+范围查询的情况下会不会用到索引

mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止使用索引

比如a = 1 and b = 2 and c > 3 and d = 4

如果建立(a,b,c,d)顺序的索引,d是用不到索引的,

如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整(建立索引时他们三个的顺序)

索引列不能参与计算,保持列“干净”,

以下的截图可以很直观的看到为什么不能让索引列参与计算,表里的数据只有6行

image.png
image.png

你可能感兴趣的:(MySQL优化相关的名词以及一些简单的优化)