第41讲:MySQL内置的QL性能分析工具

news/2024/5/2 7:43:37/文章来源:https://blog.csdn.net/weixin_44953658/article/details/128073829

文章目录

    • 1.SQL性能分析的概念
    • 2.分析数据库中SQL的执行频率
    • 3.数据库中的慢查询日志
      • 3.1.开启慢查询日志功能
      • 3.2.模拟慢SQL查询观察日志内容
    • 4.Profile查看SQL每个阶段的耗时
      • 4.1.开启Profile操作
      • 4.2.随便执行一些查询语句
      • 4.3.查询执行SQL的耗时
      • 4.4.查询某一条SQL每个阶段的耗时
      • 4.5.查询某条SQL的CPU使用情况
    • 5.Explain分析SQL的执行计划
      • 5.1.Explain执行计划中各个字段的含义
      • 5.2.分析几个SQL的执行计划重点演示id字段的含义
      • 5.3.分析几个SQL的执行计划重点演示什么样的SQL会产生什么样的访问表类型

1.SQL性能分析的概念

在做SQL优化这类的操作时,我们首先要明确什么类型的SQL语句在数据库中的执行频率最高,往往要做SQL优化的都是SELECT查询语句,增删改的写入基本是固定的格式,也不需要优化。

例如当一个表中的数据量很大,但是基本上都是写入和更新的动作,那么我们大可不必去对表的索引和查询语句优化,是没有太大必要的,往往的优化都是对大量的查询进行优化的。

在SQL优化过程中,索引的优化占据了主导的地方,往往会对频繁查询的字段建立一个索引,增大查询的速度。

2.分析数据库中SQL的执行频率

在性能分析中,首先要明确数据库中哪类的SQL操作占的比例比较大,从而对症下药。

通过以下指令可以查询数据库中各项SQL操作的占比。

mysql> show global status like 'Com_______';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_binlog    | 0     |
| Com_commit    | 30    |
| Com_delete    | 23    |
| Com_import    | 0     |
| Com_insert    | 192   |
| Com_repair    | 0     |
| Com_revoke    | 5     |
| Com_select    | 4325  |
| Com_signal    | 0     |
| Com_update    | 67    |
| Com_xa_end    | 0     |
+---------------+-------+
11 rows in set (0.00 sec)

Com后面是7个下划线,表示后面的内容是7个,查询SQL的执行频率可以是全局下的统计,也可以是当前会话中的统计。

global是查询全局的SQL执行频率,session是查询当前会话中的SQL查询频率。

我们重点关注Com_select、Com_insert、Com_update、Com_delete四类SQL的频率。

根据上面输出的结果,可以分析出该数据库的查询操作占比很高。

3.数据库中的慢查询日志

通过前面的SQL执行频率,我们能得知,在数据库中查询的频率最为频繁,那么应该如何定位哪些查询语句需要优化呢?针对这些需求可以通过MySQL的慢查询日志,从中得到应该对那些SQL进行优化。

慢查询日志记录了所有执行时间超过指定参数的所有SQL查询语句,通过long_query_time参数可以设置SQL执行的超时时间,当超过该参数值的所有SQL语句将被记录到慢查询日志中,该参数的单位是秒,默认是10秒。

慢查询日志默认情况下没有开启,可以通过下面的指令查看有没有开启慢查询日志。

mysql> show variables like 'slow_query_log';
+----------------+-------+
| Variable_name  | Value |
+----------------+-------+
| slow_query_log | OFF   |
+----------------+-------+
1 row in set (0.00 sec)

3.1.开启慢查询日志功能

1.配置MySQL的配置文件开启慢查询日志
[root@mysql ~]# vim /etc/my.cnf
slow_query_log=1						#开启慢查询日志
long_query_time=2						#设置查询SQL的超时时间,当超过2秒后,就被记录到慢查询日志中2.重启MySQL
[root@mysql ~]# systemctl restart mysqld3.慢SQL日志文件路径
[root@mysql ~]# ll /var/lib/mysql/mysql.sock.lock
-rw------- 1 mysql mysql 5 529 17:14 /var/lib/mysql/mysql.sock.lock

3.2.模拟慢SQL查询观察日志内容

1)执行一个超长时间的查询SQL

找一张数据量大的表,执行查询指令。

select * from dabiao;

2)观察慢SQL日志

[root@mysql ~]# cat /var/lib/mysql/mysql-slow.log 
/usr/sbin/mysqld, Version: 8.0.26 (MySQL Community Server - GPL). started with:
Tcp port: 3306  Unix socket: /var/lib/mysql/mysql.sock
Time                 Id Command    Argument
# Time: 2022-05-29T09:17:14.628770Z
# User@Host: root[root] @  [192.168.20.118]  Id:     8
# Query_time: 38.426420  Lock_time: 0.000587 Rows_sent: 27126  Rows_examined: 27126
use db_1;
SET timestamp=1653815796;				#SQL执行的时间
select * from dabiao;					#完整的SQL语句

我们可以定期的翻一翻慢SQL日志,找出执行频繁且时间很长的SQL,进行优化。

4.Profile查看SQL每个阶段的耗时

在前面提到的慢SQL日志,虽然超过了我们指定时间,就会被记录到慢SQL里,但是也很有可能一些小的业务逻辑,SQL写的不是那么好,本来1秒就可以搞定的查询,结果用了七八秒,加入慢查询的时间是10秒,那么就不会记录到慢SQL里。

这时我们就可以通过Profile这个工具来分析当前会话或者全局模式下执行的SQL耗时,也可以指定查询某一条SQL每个阶段的耗时。

4.1.开启Profile操作

1)首先查一下当前数据库支不支持profile

mysql> select @@have_profiling;
+------------------+
| @@have_profiling |
+------------------+
| YES              |
+------------------+
1 row in set, 1 warning (0.00 sec)

2)查看当前MySQL是否开启profile

默认是关闭状态,0表示关闭,1表示开启。

mysql> select  @@profiling;
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+
1 row in set, 1 warning (0.00 sec)

3)开启profile操作

可以针对当前会话session开启profile,也可以针对global开启。

mysql> set global profiling = 1;mysql> select  @@profiling;
+-------------+
| @@profiling |
+-------------+
|           1 |
+-------------+
1 row in set, 1 warning (0.00 sec)

4.2.随便执行一些查询语句

mysql> select * from tb_user;
mysql> select * from tb_user where id = 1 ;
mysql> select * from tb_user where xm = '余伟' ;

4.3.查询执行SQL的耗时

通过以下指令可以看到每条SQL语句的耗时,可以看到查询同样的一条数据,例如9和12,指定主键索引查询的耗时为0.00083750,指定常规索引查询的耗时为0.00100925,有明显的差距。

mysql> show profiles;
+----------+------------+---------------------------------------------+
| Query_ID | Duration   | Query                                       |
+----------+------------+---------------------------------------------+
|        1 | 0.00069850 | select @@version_comment limit 1            |
|        2 | 0.00041775 | select  @@profiling                         |
|        3 | 0.00039950 | SELECT DATABASE()                           |
|        4 | 0.00038075 | SELECT DATABASE()                           |
|        5 | 0.00381225 | show databases                              |
|        6 | 0.00467850 | show tables                                 |
|        7 | 0.00531375 | select * from db_user                       |
|        8 | 0.01484700 | select * from tb_user                       |
|        9 | 0.00083750 | select * from tb_user where id = 1          |
|       10 | 0.00070725 | select * from tb_user where name = 余伟     |
|       11 | 0.00044275 | select * from tb_user where name = '余伟'   |
|       12 | 0.00100925 | select * from tb_user where xm = '余伟'     |
+----------+------------+---------------------------------------------+
12 rows in set, 1 warning (0.00 sec)

4.4.查询某一条SQL每个阶段的耗时

查询刚刚show profiles结构中id为9的SQL每个执行阶段的耗时,主要看executing字段对应的耗时。

mysql> show profile for query 9;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000141 |
| Executing hook on transaction  | 0.000014 |
| starting                       | 0.000044 |
| checking permissions           | 0.000020 |
| Opening tables                 | 0.000113 |
| init                           | 0.000019 |
| System lock                    | 0.000024 |
| optimizing                     | 0.000029 |
| statistics                     | 0.000142 |
| preparing                      | 0.000038 |
| executing                      | 0.000112 |
| end                            | 0.000019 |
| query end                      | 0.000011 |
| waiting for handler commit     | 0.000023 |
| closing tables                 | 0.000023 |
| freeing items                  | 0.000033 |
| cleaning up                    | 0.000033 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.00 sec)

4.5.查询某条SQL的CPU使用情况

mysql> show profile cpu for query 9;
+--------------------------------+----------+----------+------------+
| Status                         | Duration | CPU_user | CPU_system |
+--------------------------------+----------+----------+------------+
| starting                       | 0.000141 | 0.000000 |   0.000134 |
| Executing hook on transaction  | 0.000014 | 0.000000 |   0.000012 |
| starting                       | 0.000044 | 0.000000 |   0.000045 |
| checking permissions           | 0.000020 | 0.000000 |   0.000019 |
| Opening tables                 | 0.000113 | 0.000000 |   0.000115 |
| init                           | 0.000019 | 0.000000 |   0.000017 |
| System lock                    | 0.000024 | 0.000000 |   0.000024 |
| optimizing                     | 0.000029 | 0.000000 |   0.000029 |
| statistics                     | 0.000142 | 0.000000 |   0.000144 |
| preparing                      | 0.000038 | 0.000000 |   0.000036 |
| executing                      | 0.000112 | 0.000000 |   0.000116 |
| end                            | 0.000019 | 0.000000 |   0.000014 |
| query end                      | 0.000011 | 0.000000 |   0.000012 |
| waiting for handler commit     | 0.000023 | 0.000000 |   0.000023 |
| closing tables                 | 0.000023 | 0.000000 |   0.000023 |
| freeing items                  | 0.000033 | 0.000000 |   0.000033 |
| cleaning up                    | 0.000033 | 0.000000 |   0.000033 |
+--------------------------------+----------+----------+------------+
17 rows in set, 1 warning (0.00 sec)

5.Explain分析SQL的执行计划

在前面判定一个SQL的执行效率是否高,主要是根据执行的时长来决定的,但是不一定精准。

我们可以通过EXPLAIN或者DESC指令,去分析一条SQL的执行计划,可以根据执行计划返回的内容判断SQL执行的效率。

EXPLAIN的语法结构:EXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件

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

下面是EXPLAIN分析一个SQL的执行计划所输出的内容,可以看到包含了很多字段,那么这些字段有什么含义呢?我们下面一起来看一下。

image-20220529225526299

几个主要字段的含义如下:

  • id字段:

    • 代表select查询的序列号,表示查询语句中select语句或者操作表的顺序。
    • 单表查询只有一行数据,id永远为1。
    • 多表查询时,如果id相同,那么执行顺序从上到下依次执行。
    • 如果没有多表查询,例如子查询,一条SQL语句中有多个select语句,那么此时id显示的就会不同,id的值越大,那么就会越先执行。
  • select_type字段:

    • 表示该条SQL语句的查询类型,常见的取值有SIMPLE(简单表查询,不使用表连接或者子查询,只是单表查询)、PRIMARY(主查询)、UNION(联合查询)、SUBQUERY(SELECT/WHERE之后包含的子查询)。
  • table字段:

    • 查询的表名。
  • type字段:

    • 连接表的类型、访问表的类型,性能由好到差的连接类型为:NULL、system、const、eq_ref、ref、range、index、all。
    • 其中性能最好的是NULL,性能最差的是all,但是几乎在业务数据库中不可能会出现NULL类型的表连接,因为NULL表示不访问任何表。
    • system表示查询的是系统表,访问系统表时才会看到类型是system。
    • conset类型可以说是性能很好的类型了,当使用主键索引、唯一索引作为条件访问表时就会出现conset类型,此时性能是最好的。
    • 当使用常规索引,也就是我们创建的索引作为条件访问表时,类型就是ref。
    • 当出现index类型时,表示虽然也是用索引查询表了,但是对索引进行了全部扫描,性能也不高。
    • 在优化SQL时,尽量将连接类型优化到前面几个类型访问表,性能是最好的,当然也需要根据业务的自身逻辑去优化,尽量不要出现all,当出现all时就表示要全表扫描了。
  • possible_keys字段:

    • 显示可能会使用到表中的那些索引,一个或者多个。
  • key字段:

    • 实际使用哪个索引查询的数据,如果为NULL,就表示没有使用使用索引。
  • key_len字段:

    • 索引使用的字节数,该值为索引字段最大的可能长度,但是也非实际使用的长度,虽然不是特别精准,但是长度越短越好。
  • rows字段:

    • 认为要执行查询的行数,也就是认为要查询多少行才能拿到对应的结果,也是一个估值,不是那么精准。
  • filtered字段:

    • 表示返回结果的行数占读取行数的百分比,该字段的值越大越好,越大表示我们读取的行就是我们要查询结果的行,更加精准,性能高。

在这么多字段中,我们重点关注id、type、possible_key、key、key_len、filtered这几个字段的值,根据这些值就有了优化SQL的因素。

5.2.分析几个SQL的执行计划重点演示id字段的含义

id字段:代表select查询的序列号,表示查询语句中select语句或者操作表的顺序。

  • 单表查询只有一行数据,id永远为1。
  • 多表查询时,如果id相同,那么执行顺序从上到下依次执行。
  • 如果没有多表查询,例如子查询,一条SQL语句中有多个select语句,那么此时id显示的就会不同,id的值越大,那么就会越先执行。

1)单表查询只有一行数据,id永远为1。

explain select * from tb_user where id = '1';

image-20220529233828219

2)多表查询时,如果id相同,那么执行顺序从上到下依次执行。

只要是多表查询,那么多行记录的id不会自增,而是显示相同的值,并且执行顺序是从上到下依次执行的。

下面这条SQL是查询每个人员属于哪个部门的,共用到两张表分别是人员信息表和部门信息表。

SELECTr.xm,r.zw,b.bmmc 
FROMryxxb AS rLEFT OUTER JOIN bmxxb AS b ON r.bm_id = b.id;

下面我们通过EXPLAIN来分析该条SQL的执行顺序。

explain select r.xm,r.zw,b.bmmc from ryxxb as r left outer join bmxxb as b on r.bm_id = b.id; 

分析结果如下,id值相同,表的执行顺序从上到下,首先查询部门表,然后再查询人员信息表。

image-20220529234641209

一般情况下from之后的表都是先执行的,如果是三张表的多表查询,其中包含中间表,那么中间表一定是第二个执行的。

3)ID值不同,谁的ID值大谁先执行。

我们执行一个子查询的SQL,分析他的执行计划。

下面这个子查询的SQL是要查询人员信息表中薪资大于销售部全部人员薪资的其他人员信息。

下面这个SQL中select执行的顺序首先是SELECT id FROM bmxxb WHERE bmmc = '销售部',然后是SELECT xz FROM ryxxb WHERE bm_id IN这一条,最后是select * from ryxxb

SELECT* 
FROMryxxb 
WHERExz > ALL (SELECT xz FROM ryxxb WHERE bm_id IN ( SELECT id FROM bmxxb WHERE bmmc = '销售部' ));

通过explain观察执行计划。

explain select * from ryxxb where xz > all (select xz from ryxxb where bm_id in (select id from bmxxb where bmmc = '销售部'));

执行计划如下,可以看到ID有不一样的了,那么ID值越大就说明越先执行,那么bmxxb肯定是第一个执行,此时还有一个ID为2的表,相同ID,按照顺序执行,那么第二个执行的就是ryxxb表,ID为1最小,那么就会最后执行ryxxb表。

image-20220529235822084

5.3.分析几个SQL的执行计划重点演示什么样的SQL会产生什么样的访问表类型

1)NULL类型的访问表,性能最高。

NULL类型几乎在业务逻辑中出现的很少,因为不查询任何表时,才会返回NULL。

explain select 'A' ;

image-20220530000242114

2)conset类型的访问表,性能较好。

当使用主键索引或者唯一索引访问表时,都会出现conset类型。

explain select * from tb_user where id = '1' ;

image-20220530000413598

3)ref类型的访问表,性能略好。

当使用常规索引访问表时,会出现ref类型。

mysql> explain select * from tb_user where xm = '江睿基' ;

image-20220530000539396

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_37934.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java项目:jsp+servlet实现的新闻发布系统

作者主页:源码空间站2022 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台; 前台主要功能为: 首页、娱乐新闻、经济新闻、文化新闻、小道新闻、用户评价等; 后台主要…

目标检测论文解读复现之二十:基于改进Yolov5的地铁隧道附属设施与衬砌表观病害检测方法

前言 此前出了目标改进算法专栏,但是对于应用于什么场景,需要什么改进方法对应与自己的应用场景有效果,并且多少改进点能发什么水平的文章,为解决大家的困惑,此系列文章旨在给大家解读最新目标检测算法论文&#xff0…

ipv6地址概述——配置ipv6

个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。个人爱好: 编程,打篮球,计算机知识个人名言:海不辞水,故能成其大;山不辞石…

TMS Echo数据复制的Delphi框架

TMS Echo数据复制的Delphi框架 TMS Echo是用于数据复制的Delphi框架。它是TMS Business产品阵容的一部分,它取决于TMS Aurelius的运营。 TMS Echo允许您至少拥有两个数据库并在它们之间同步信息。您对单个客户数据库所做的更改(插入、更新、删除)可能会传输到其他数…

jenkins关联github

将Jenkins和github关联起来,实现自动化集成 GitHub侧 1、生成secret.txt secret在github上被称为token 进去GitHub --> Settings --> Developer settings --> Personal access tokens -> Generate new token创建一个新的token,勾选两处标红的地方 点…

COLMAP生成MVSNet数据集

一. colmap2mvsnet.py COLMAP可以给图像数据集标定一套相机外参及视图选择。如果想用COLMAP导出的结果输入MVSNet测试,需要把数据集(图片、相机参数等)转化为MVSNet的输入格式。MVSNet的作者yaoyao在Github上提供了colmap2mvsnet.py代码&…

Jsoup爬虫入门实战

一、Jsoup介绍 jsoup 是一款基于 Java 的HTML解析器,它提供了一套非常省力的API,不但能直接解析某个URL地址、HTML文本内容,而且还能通过类似于DOM、CSS或者jQuery的方法来操作数据,所以 jsoup 也可以被当做爬虫工具使用。 相关…

Nuxt 3.0.0正式发布,集成Element Plus、Ant Design Vue和Arco Design Vue脚手架

发布说明 Nuxt 是使用简便的 Web 框架,用于构建现代和高性能的 Web 应用,可以部署在任何运行 JavaScript 的平台上。 Nuxt 3.0 11天前正式发布了稳定版,3.0 基于 Vue 3,为 TypeScript 提供了 “一等公民” 支持,并进行…

汽车销量数据库(分车型、分品牌月度销量数据 2005-2021)

1、数据来源:汽车工业协会 2、时间跨度:2005年1月-2021年5月 3、区域范围:全国 4、指标说明: 该份数据包含全国各种汽车销量数十个相关指标! 该份数据包含如下指标: 轿车:一汽大众、上海大…

steam搬砖项目月入过万靠谱吗

大家好,我是阿阳 什么是国外steam游戏装备汇率差项目 一、项目介绍 其实,Steam就是一个美国的游戏平台,搬砖主要是搬的一款火遍全球的游戏CSGO的装备和饰品。CS听说过吧,这款游戏就是CS的一个系列。(通俗易懂的理解就…

2023年天津财经大学珠江学院专升本管理学原理专业考试大纲

天津财经大学珠江学院2023年高职升本科专业课考试《管理学原理》考试大纲一、本大纲系天津财经大学珠江学院2023年高职升本科《管理学原理》课程考试大纲。所列考试范围出自徐碧琳主编的教材《管理学原理(第二版)》,机械工业出版社&#xff0…

最全面的SpringMVC教程(二)——SpringMVC核心技术篇

前言 本文为 【SpringMVC教程】核心技术篇 相关详细介绍,具体将对视图和模型拆分,重定向与转发,RequestMapping与其衍生注解,URL 模式匹配,牛逼的传参,设定字符集,返回json数据(序列…

全球价值链GVC总出口分解(2011-2014年)

1、数据来源:ICIO数据库 2、时间跨度:2011-2014年 3、区域范围:世界 4、指标说明: 全球价值链分析(Global Value Chain analysis,简称GVC分析)为解决传统贸易统计中…

【Hack The Box】linux练习-- seal

HTB 学习笔记 【Hack The Box】linux练习-- seal 🔥系列专栏:Hack The Box 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📆首发时间:🌴2022年11月17日🌴 &#x1f36d…

十万部冷知识:足球踢进了观众席,观众能把球拿走吗?

在看足球比赛的时候,我们经常会看到球员一脚射门踢偏了,球被打飞的情况,这时候球可就奔着观众席去了。就是因为考虑到有这种情况的发生,在比赛之前,比赛组织者,都会提前准备很多的备用球,当球被…

Java 编程性能调优

把 Java 性能调优分成 5 个层级:Java 编程、多线程、JVM 性能检测、设计模式、数据库性能,每个层级下都覆盖了最常见的优化问题。下面分别给你梳理一下: 可参考地址:Java性能调优全攻略来了_着火点的博客-CSDN博客_java性能调优 …

TMS Logging提供了短日志输出

TMS Logging提供了短日志输出 TMS Logging Compact跨平台框架以最小的代码量为各种目标提供了短日志输出。 TMS记录惊人属性: 登录到一个或多个输出处理程序,如控制台、HTML、文本、文本、CSV文件、TCP/IP、浏览器、Windows事件日志等,。。。…

【Hack The Box】linux练习-- Ophiuchi

HTB 学习笔记 【Hack The Box】linux练习-- Ophiuchi 🔥系列专栏:Hack The Box 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📆首发时间:🌴2022年11月27日🌴 &#x1…

【Java系列】一篇文章快速了解Java语言概述

Java语言概述1.Java简介2.JVM2.1JVM介绍2.2JVM特性3.Java特性4.搭建Java程序开发环境5.编写第一个Java应用程序6.小结第一个程序1.Java简介 java是面向对象的一门程序设计语言随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。后台开发&#x…

深度学习第四课——深度卷积网络(week 2)

目录 二、深度卷积网路 2.1 经典网络结构 2.1.1 LeNet - 5 2.1.2 AlexNet 2.1.3 VGG - 16 2.2 残差网络(ResNets - Residual Networks) 2.3 残差网络为什么有用 2.4 网络中的网络及11卷积 2.5 Inception网络 2.5.1 介绍 2.5.2 应用 2.6 使用…