【MySQL】分析SQL的几种方式
  pgSCHb2FgBf2 2023年11月02日 23 0



文章目录

  • 一、查看SQL执行频率
  • 二、定位低效率执行SQL
  • 1. show processlist
  • 2. 慢查询日志
  • 三、explain分析执行计划
  • 1. id
  • 2. select_type
  • 3. type
  • 4. key
  • 5. extra
  • 四、show profile


一、查看SQL执行频率

show session status:显示 session 级的统计结果(不写参数默认session)

show global status:显示 global 级的统计结果

mysql> show status like 'Com_______';   -- 查看各种类型SQL的执行次数
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog    | 0     |
| Com_commit    | 2     |
| Com_delete    | 0     |
| Com_import    | 0     |
| Com_insert    | 35    |
| Com_repair    | 0     |
| Com_revoke    | 0     |
| Com_select    | 13    |
| Com_signal    | 0     |
| Com_update    | 0     |
| Com_xa_end    | 0     |
+---------------+-------+
11 rows in set (0.00 sec)

mysql> show global status like 'Com_______';   -- 查看各种类型SQL的执行次数
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog    | 0     |
| Com_commit    | 4     |
| Com_delete    | 4     |
| Com_import    | 0     |
| Com_insert    | 35    |
| Com_repair    | 0     |
| Com_revoke    | 0     |
| Com_select    | 291   |
| Com_signal    | 0     |
| Com_update    | 11    |
| Com_xa_end    | 0     |
+---------------+-------+
11 rows in set (0.00 sec)

mysql> show status like 'Innodb_rows_%';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Innodb_rows_deleted  | 0     |   -- 删除的行数
| Innodb_rows_inserted | 0     |   -- 插入的行数
| Innodb_rows_read     | 0     |   -- 读取的行数
| Innodb_rows_updated  | 0     |   -- 更新的行数
+----------------------+-------+
4 rows in set (0.00 sec)

参数

含义

Com_select

执行 select 操作的次数,一次查询只累加 1。

Com_insert

执行 INSERT 操作的次数,对于批量插入的 INSERT 操作,只累加一次。

Com_update

执行 UPDATE 操作的次数。

Com_delete

执行 DELETE 操作的次数。

Innodb_rows_read

select 查询返回的行数。

Innodb_rows_inserted

执行 INSERT 操作插入的行数。

Innodb_rows_updated

执行 UPDATE 操作更新的行数。

Innodb_rows_deleted

执行 DELETE 操作删除的行数。

Connections

试图连接 MySQL 服务器的次数。

Uptime

服务器工作时间。

Slow_queries

慢查询的次数。

Com_xxx :这些参数对于所有存储引擎的表操作都会进行累计。

Innodb_xxx :这几个参数只是针对InnoDB 存储引擎的,累加的算法也略有不同。

二、定位低效率执行SQL

1. show processlist

查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化

【MySQL】分析SQL的几种方式_子查询

1) id列,用户登录mysql时,系统分配的"connection_id",可以使用函数connection_id()查看

2) user列,显示当前用户。如果不是root,这个命令就只显示用户权限范围的sql语句

3) host列,显示这个语句是从哪个ip的哪个端口上发的,可以用来跟踪出现问题语句的用户

4) db列,显示这个进程目前连接的是哪个数据库

5) command列,显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等

6) time列,显示这个状态持续的时间,单位是秒

7) state列,显示使用当前连接的sql语句的状态,很重要的列。state描述的是语句执行中的某一个状态。一个sql语句,以查询为例,可能需要经过copying to tmp table、sorting result、sending data等状态才可以完成

8) info列,显示这个sql语句,是判断问题语句的一个重要依据

2. 慢查询日志

通过慢查询日志定位那些执行效率较低的 SQL 语句,用–log-slow-queries[=file_name]选项启动时,mysqld 写一个包含所有执行时间超过 long_query_time 秒的 SQL 语句的日志文件

MySQL Server 层四个日志

三、explain分析执行计划

列名

描述

id

在一个大的查询语句中每个SELECT关键字都对应一个 唯一的id

select_type

SELECT关键字对应的那个查询的类型

table

表名

partitions

匹配的分区信息

type *

针对单表的访问方法

possible_keys

可能用到的索引

key *

实际上使用的索引

key_len *

实际使用到的索引长度

ref

当使用索引列等值查询时,与索引列进行等值匹配的对象信息

rows *

预估的需要读取的记录条数

filtered

某个表经过搜索条件过滤后剩余记录条数的百分比

Extra *

一些额外的信息,排序…

type

完整的访问方法如下: system ,const ,eq_ref ,ref ,fulltext ,ref_or_null ,index_merge , unique_subquery ,index_subquery , range , index ,ALL

  • const:当我们根据主键或者唯一二级索引列与常量等值匹配时,对单表的访问方法就是const,只匹配一条记录
  • ref:普通二级索引等值匹配常量
  • range:走索引的范围查询
  • index_merge:用到多个索引(多个select,比如子查询)
  • index:需要扫描整个索引树(比如联合索引只用到右边的字段,和查询数据可以组成联合索引)
  • ALL:不走索引,全表扫描,读磁盘

key: 用到的索引

key_len: 用到索引的占用的字节数,针对联合索引有一定的参考价值

ref

  • const:常量等值匹配

rows: 预估需要读取的记录数,越小越好

Extra

  • using filesort:排序
  • using index:表示使用索引,且没有回表(覆盖索引)
  • using where:表示使用索引,且需要回表
  • using index condition:索引下推
1. id

1) id 相同表示加载表的顺序是从上到下

explain select * from t_role r, t_user u, user_role ur where r.id = ur.role_id and u.id = ur.user_id ;

【MySQL】分析SQL的几种方式_子查询_02

2) id 不同id值越大,优先级越高,越先被执行

EXPLAIN SELECT * FROM t_role WHERE id = (SELECT role_id FROM user_role WHERE user_id = (SELECT id FROM t_user WHERE username = 'stu1'))

【MySQL】分析SQL的几种方式_数据库_03

3) id 有相同,也有不同。id相同的可以认为是一组,从上往下顺序执行;在所有的组中,id的值越大,优先级越高,越先执行

EXPLAIN SELECT * FROM t_role r , (SELECT * FROM user_role ur WHERE ur.`user_id` = '2') a WHERE r.id = a.role_id ;

【MySQL】分析SQL的几种方式_MySQL_04

2. select_type

表示 SELECT 的类型,常见的取值,如下表所示:

select_type

含义

SIMPLE

简单的select查询,查询中不包含子查询或者UNION

PRIMARY

查询中若包含任何复杂的子查询,最外层查询标记为该标识

SUBQUERY

在SELECT 或 WHERE 列表中包含了子查询

DERIVED

在FROM 列表中包含的子查询,被标记为 DERIVED(衍生) MYSQL会递归执行这些子查询,把结果放在临时表中

UNION

若第二个SELECT出现在UNION之后,则标记为UNION ; 若UNION包含在FROM子句的子查询中,外层SELECT将被标记为 : DERIVED

UNION RESULT

从UNION表获取结果的SELECT

【MySQL】分析SQL的几种方式_sql_05

【MySQL】分析SQL的几种方式_MySQL_06

3. type

type 显示的是访问类型,是较为重要的一个指标,可取值为:

type

含义

NULL

MySQL不访问任何表,索引,直接返回结果

system

表只有一行记录(等于系统表),这是const类型的特例,一般不会出现

const

表示通过索引一次就找到了,const 用于比较primary key 或者 unique 索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MySQL 就能将该查询转换为一个常亮。const于将 “主键” 或 “唯一” 索引的所有部分与常量值进行比较

eq_ref

类似ref,区别在于使用的是唯一索引,使用主键的关联查询,关联查询出的记录只有一条。常见于主键或唯一索引扫描

ref

非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,返回所有匹配某个单独值的所有行(多个)

range

只检索给定返回的行,使用一个索引来选择行。 where 之后出现 between , < , > , in 等操作。

index

index 与 ALL的区别为 index 类型只是遍历了索引树, 通常比ALL 快, ALL 是遍历数据文件。

all

将遍历全表以找到匹配的行

NULL > system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

system > const > eq_ref > ref > range > index > ALL

4. key

possible_keys : 显示可能应用在这张表的索引, 一个或多个。

key : 实际使用的索引, 如果为NULL, 则没有使用索引。

key_len : 表示索引中使用的字节数, 该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下, 长度越短越好 。

5. extra
  • using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取, 称为 “文件排序”,效率低
  • using temporary:使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于 order by 和 group by; 效率低
  • using where:表示使用索引,且需要回表
  • using index:表示相应的select操作使用了覆盖索引, 避免访问表的数据行, 效率不错
  • using index condition:联合索引生效,但是需要回表,并没有用到覆盖索引,需要优化,避免使用select *

四、show profile

开启profiling 开关:set profiling=1;

执行完SQL后,再执行show profiles 指令, 来查看SQL语句执行的耗时:

【MySQL】分析SQL的几种方式_sql_07

通过show profile for query [query_id] 语句可以查看到该SQL执行过程中每个线程的状态和消耗的时间:

【MySQL】分析SQL的几种方式_MySQL_08


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

pgSCHb2FgBf2