查看SQL执行频率
MySQL 客户端连接成功后,通过show[session|global] status 命令可以提供服务器状态信息。通过如下指令可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次:
|  |  | 
结果如下:
|  |  | 
查询慢日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。MySQL的慢查询日志默认没有开启,执行一下SQL查看慢日志开启状态:
1SHOW VARIABLES LIKE 'slow_query_log';
需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
|  |  | 
重启MySQL服务,本机环境为win10的WSL2,直接执行以下命令:
|  |  | 
profile详情
show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪去了。通过have_profiling参数,能够看到当前MySQL是否支持profile操作:
|  |  | 
默认profiling是关闭的,可以通过set语句在session/global级别开启profiling:
|  |  | 
执行完查询语句后再执行show profiles,结果如下:
|  |  | 
explain 执行计划
EXPLAIN 或者 DESC 命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。语法如下:
|  |  | 
结果如下:
|  |  | 
EXPLAIN 输出列如下:
| Column | JSON Name | Meaning | 
|---|---|---|
| id | select_id | SELECT标识符 | 
| select_type | None | SELECT类型 | 
| table | table_name | 输出行table | 
| partitions | partitions | 匹配的分区 | 
| type | access_type | 连接类型 | 
| possible_keys | possible_keys | 可能的索引选择 | 
| key | key | 实际选择的索引 | 
| key_len | key_length | 所选键的长度 | 
| ref | ref | 与索引比较的列 | 
| rows | rows | 估计要检查的行 | 
| filtered | filtered | 按table条件过滤的行百分比 | 
| Extra | None | 扩展信息 | 
😀 Note 详细解释可参考 [官方文档]
- 
id行标识,如果没有子查询或者联合查询,这个值是1,id列值越大越先执行,如果一样大,那么就从上往下依次执行
- 
select_type查询的类型,可以是下表的任何一种类型select_type 类型说明 SIMPLE简单 SELECT(不使用UNION或子查询)PROMARY最外层的 SELECTUNIONUNION中第二个或之后的SELECT语句DEPENDENT UNIONUNION中第二个或之后的SELECT语句取决于外面的查询UNION RESULTUNION的结果SUBQUERY子查询中的第一个 SELECTDEPENDENT SUBQUERY子查询中的第一个 SELECT,取决于外面的查询DERIVED衍生表(FROM自居中的子查询) MATERIALIZED物化子查询 UNCACHEABLE SUBQUERY结果集无法缓存的子查询,必须重新评估外部查询的每一行 UNCACHEABLE UNIONUNION中第二个或之后的SELECT,属于无法缓存的子查询
⭐
DEPENDENT意味着使用了关联子查询
- 
table:输出行所引用表的名称,也可以是以下值之一:- <unionM,N>: 引用id为M和N UNION之后的结果。
- : 引用id为N的结果派生出的表,派生表可以是一个结果集,例如派生自FROM中子查询的结果。 
- : 引用id为N的子查询结果物化得到的表,即生成一个临时表保存子查询的结果。 
 
- 
partitions:v5.7之前该项是explain partitions显示的选项,v5.7之后成为了默认选项,该列显示的为分区表中的分区情况,非分区表该字段为空(null)。
- 
type( 重要 ):连接类型 - 
system表中只有一行数据或者是空表,这是const类型的一个特例,且只能用于MyISAM和Memory表,如果是InnoDB引擎表,type列在这个情况通常都是all或者index
- 
const最多只有一行记录匹配。当联合主键或唯一索引的所有字段跟常量值比较时,join类型为const。其他数据库也叫做唯一索引扫描
- 
eq_ref多表join时,对于来自前面表的每一行,在当前表中只能找到一行,这可能是除了system和const之外最好的类型,当主键或唯一非NULL索引的所有字段都被当做join连接时会出现此类型。eq_ref可用于使用’=‘操作符作比较的索引列,比较的值可以是常量,也可以是使用此表之前读取的表的列表达式。
- 
ref对于来自前面表的每一行,在此表的索引中可以匹配到多行,若连接只用到索引的最左前缀或索引不是主键或唯一索引时,使用ref类型(也就是说,此类型能够匹配到多行连接)。ref可用于使用=或<=>操作符作比较的索引列。
- 
fulltext用于全文索引的时候是这个类型,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在,mysql不管代价,优先选择使用全文索引
- 
ref_or_null类似于ref类型,只是增加了null值得比较,实际用的不多
- 
index_merge此类型表示查询使用两个以上索引,最后取交集或者并集,常见and,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取多个索引,性能可能大部分时间都不如range。
- 
unique_subquery用于WHERE中的IN形式子查询,子查询返回不重复值唯一值,可以完全替换子查询,效率更高。 该类型替换了下面形式的IN子查询的ref:value IN (select primary_key FROM single_table WHERE some_expr)
- 
index_subquery该连接类型类似于unique_subquery。适用于非唯一索引,可以返回重复值
- 
range索引范围查询,常见于使用=<>>>=<<=IS NULL<=>BETWEENIN或者LIKE等运算符的查询中。
- 
index索引全表扫描,把索引从头到尾扫一遍。这里包含两种情况: 一种是查询使用了覆盖索引,那么它只需要扫描索引就可以获得数据,这个效率要比全表扫描要快,因为索引通常比数据表小,而且还能避免二次查询。在extra中显示Using index,反之,如果在索引上进行全表扫描,没有Using index的提示。
- 
all全表扫描,性能较差
 
- 
- 
possible_keys:查询可能用到的索引,如果此列是 NULL,则没有用到索引。
- 
key:表示MySQL实际决定使用的索引,如果MySQL决定使用其中一个 possible_keys索引来查找行,则该索引将作为键值列出。
- 
key_length:查询用到的索引长度(字节), 如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,用多少算多少。例如组合索引为 idx_username_create_time,当查询语句为select * from user where username='qqq'时,只用到了username字段,那么key_len只会计算username字段占用的字节数,假如username字段类型为varchar(50)NOT NULL,字符编码为utf8mb3(utf8编码一个字符占用3个字节,gbk编码一个字符占2字节),记录字符串长度占用2字节,记录字段不为空占用1字节(若没有NOT NULL限制则不占用这1个字节)那么key_len为 50 * 3 + 2 + 1 = 153字节
- 
ref:如果使用的是常数等值查询,这里会显示 const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列表发生了内部隐式转换,这里可能显示为func。
- 
rows( 重要 ): rows也是一个重要的字段,这是MySQL估算的需要扫描的行数(不是精确值)。这个值非常直观显示SQL的效率好坏,原则上rows越少越好。
- 
filtered:该字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。 
- 
Extra( 重要 ): EXPLAIN中很多额外的信息会在Extra字段显示,常见的有以下:- distinct: 在- select部分使用了- distinct关键字
- Using filesort: 当- Extra中有- Using filesort时,表示MySQL需额外的排序操作,不能通过索引顺序到达排序效果,一般有- Using filesort都建议优化去掉,因为这样的查询CPU资源消耗较大。
- Using index: “覆盖索引扫描”,表示查询在索引树种就可查找所需数据,不用扫描表数据文件,往往说明性能不错。
- Using temporary: 查询有使用临时表,一般出现于排序,分组和多表join的情况,查询效率不高,建议优化。