🗒️MySQL
2023-9-20
| 2023-10-18
字数 3025阅读时长 8 分钟
type
status
date
slug
summary
tags
category
icon
password
MyISAMInnoDB索引结构B+Tree 索引结构hash 索引结构索引分类:索引的存储形式通过索引查询的执行过程SQL 性能分析SQL执行频率慢查询日志explain 执行计划Explain 执行计划中各个字段的含义:索引使用(失效)最左前缀法则范围查询索引列运算字符串不加引号 模糊查询or连接条件(只要一边没有索引就会失效)数据分布影响SQL提示覆盖索引

MyISAM

InnoDB

索引结构

B+Tree 索引结构

notion image

hash 索引结构

思考:为什么InnoDB存储引擎选择使用B+tree索引结构?
notion image

索引分类:

notion image

索引的存储形式

而在在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种:聚集索引、二级索引
notion image
聚集索引的结构就是一个B+Tree,他的叶子节点挂的就是一行数据,比如主键id为5,叶子节点为5,那么叶子节点下的数据就为id的为5的这行数据
二级索引的结构也是一个B+Tree,二级索引的叶子节点存储的是当前值所在行的id,如name是一个二级索引,值为:“张三”,当前id为 3,那么叶子节点存储的值就是3。
notion image

通过索引查询的执行过程

notion image

SQL 性能分析

SQL执行频率

MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信 息。通过如下指令,可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次:
notion image
通过查询SQL的执行频次,我们就能够知道当前数据库到底是增删改为主,还是查询为主。 那假 如说是以查询为主,我们又该如何定位针对于那些查询语句进行优化呢? 我们可以借助于慢查询日志。

慢查询日志

Linux 开启慢查询日志方式:
notion image
notion image
检查慢查询日志 :可以清楚的看到某段时间当中那些sql语执行效率低
notion image
show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪里去了。通过have_profiling 参数,能够看到当前MySQL是否支持profile操作:
notion image

explain 执行计划

EXPLAIN 或者 DESC命令获取 MySQL 如何执行 SELECT 语句的信息,包括在 SELECT 语句执行 过程中表如何连接和连接的顺序。
语法:

Explain 执行计划中各个字段的含义:

notion image
notion image

索引使用(失效)

最左前缀法则

查询条件必须包含最左边的列,不包含最左边的列将导致索引全部失效,跳过中间的列会导致部分索引失效(如果跳过中间列,中间列后面字段索引失效)。
notion image
示例:
notion image
这里可以计算出 status 字段索引长度为 5 (54 - 49 = 5)
notion image
这里可以得出 age 索引长度为 2,profession 索引长度为 47
notion image
未使用最左边的条件导致索引失效
notion image
联合索引跳过中间字段导致部分索引失效
notion image
最左前缀法则与条件顺序无关,条件包含最左边的列即可
notion image
注意 : 最左前缀法则中指的最左边的列,是指在查询时,联合索引的最左边的字段(即是 第一个字段)必须存在,与我们编写SQL时,条件编写的先后顺序无关。(联合索引被跳过的字段后面字段的都会失效)

范围查询

联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效。
当范围查询使用> 或 < 时,走联合索引了,但是索引的长度为49,就说明范围查询右边的status字 段是没有走索引的。
notion image
解决方案:在业务允许的情况下,尽可能的使用类似于 >= 或 <= 这类的范围查询,而避免使用 > 或 <
当范围查询使用>= 或 <= 时,走联合索引了,但是索引的长度为54,就说明所有的字段都是走索引的。
notion image

索引列运算

不要在索引列上进行运算操作, 索引将失效。
当根据phone字段进行函数运算操作之后,索引失效。
notion image

字符串不加引号

字符串类型字段使用时,不加引号,索引将失效。
如果字符串不加单引号,对于查询结果,没什么影响,但是数 据库存在隐式类型转换,索引将失效。
notion image

模糊查询

如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。
接下来,我们来看一下这三条SQL语句的执行效果,查看一下其执行计划: 由于下面查询语句中,都是根据profession字段查询,符合最左前缀法则,联合索引是可以生效的, 我们主要看一下,模糊查询时,%加在关键字之前,和加在关键字之后的影响。
notion image

or连接条件(只要一边没有索引就会失效)

用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到
由于age没有索引,所以即使id、phone有索引,索引也会失效。所以需要针对于age也要建立索引。
notion image
然后,我们可以对age字段建立索引。
建立了索引之后,我们再次执行上述的SQL语句,看看前后执行计划的变化。
notion image
最终,我们发现,当or连接的条件,左右两侧字段都有索引时,索引才会生效。

数据分布影响

如果绝大部分数据都满足查询条件则会走全表扫描,如果绝大部分数据都不满足查询条件则会走索引。
notion image
就是因为MySQL在查询时,会评估使用索引的效率与走全表扫描的效率,如果走全表扫描更快,则放弃 索引,走全表扫描。 因为索引是用来索引少量数据的,如果通过索引查询返回大批量的数据,则还不 如走全表扫描来的快,此时索引就会失效。

SQL提示

SQL提示,是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优 化操作的目的。(给MySQL一个提示,用那个一个索引)
1). use index : 建议MySQL使用哪一个索引完成此次查询(仅仅是建议,mysql内部还会再次进行评估)。
2). ignore index : 忽略指定的索引。
3). force index : 强制使用索引。

覆盖索引

尽量使用覆盖索引,减少select *。 那么什么是覆盖索引呢? 覆盖索引是指 查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。
notion image
示例:
notion image
notion image
使用主键 ID 查询之所以可以提高效率,是因为只需要遍历一次聚集索引,聚集索引的叶子节点记录了一整行的数据,直接返回即可。
notion image
覆盖索引:
查询需要返回的字段在当前的索引结构当中都已经找到了,这种就叫覆盖索引,不需要再进行回表,一次索引扫描就完成了。
notion image
回表 查询:
此处就是一个回表查询示例,首先会去扫描辅助索引,在辅助索引中拿到id,再去扫描聚集索引找到对应的id, 然后再从此id叶子节点下挂载的行数据中提取出需要返回的字段,如此实例中的 gender 字段
notion image
 
  • MySQL
  • Git 笔记加锁文章 -
    Loading...