【MYSQL】MYSQL 的学习教程(七)之 慢 SQL 优化思路

1. 慢 SQL 优化思路

  1. 慢查询日志记录慢 SQL
  2. explain 分析 SQL 的执行计划
  3. profile 分析执行耗时
  4. Optimizer Trace 分析详情
  5. 确定问题并采用相应的措施

1. 慢查询日志记录慢 SQL

如何定位慢SQL呢?

我们可以通过 慢查询日志 来查看慢 SQL。

①:开启慢查询日志:

  • SET global slow_query_log = ON;:设置慢查询开启的状态(ON:开启;OFF:关闭)
  • slow_query_log_file:设置慢查询日志存放的位置
  • SET global log_queries_not_using_indexes = ON;:记录没有使用索引的查询 SQL。前提是slow_query_log 的值为 ON,否则不会奏效
  • SET long_query_time = 10;:设置慢查询的阀值,单位秒。如果SQL执行时间超过阀值,就属于慢查询 记录到日志文件中

②:查看慢查询日志配置:

  • show variables like 'slow_query_log%
  • show variables like 'long_query_time'

③:慢查询日志分析工具:

mysqldumpslow:该工具是慢查询自带的分析慢查询工具,一般只要安装了mysql,就会有该工具

# 取出使用最多的10条慢查询
mysqldumpslow -s c -t 10 /var/run/mysqld/mysqld-slow.log 
# 取出查询时间最慢的3条慢查询
mysqldumpslow -s t -t 3 /var/run/mysqld/mysqld-slow.log 
# 得到按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g “left join” /database/mysql/slow-log 
# 按照扫描行数最多的
mysqldumpslow -s r -t 10 -g 'left join' /var/run/mysqld/mysqld-slow.log 

注意: 使用 mysqldumpslow 的分析结果不会显示具体完整的sql语句,只会显示sql的组成结构;

假如: SELECT * FROM sms_send WHERE service_id=10 GROUP BY content LIMIT 0, 1000;

Count: 1 Time=1.91s (1s) Lock=0.00s (0s) Rows=1000.0 (1000), vgos_dba[vgos_dba]@[10.130.229.196]
SELECT * FROM sms_send WHERE service_id=N GROUP BY content LIMIT N, N;

工具其实还有很多,并不限制只有这一种,还有 pt-query-digestmysqlsla 等,这些都是可以定位慢查询日志的小工具

慢查询原因:

  • 全表扫描:explain分析type属性all
  • 全索引扫描:explain分析type属性index
  • 索引过滤性不好:靠索引字段选型、数据量和状态、表设计
  • 频繁的回表查询开销:尽量少用select *,使用覆盖索引

<转>详解 慢查询 之 mysqldumpslow

2. explain 查看分析 SQL 的执行计划

当定位出查询效率低的 SQL 后,可以使用 explain 查看 SQL 的执行计划。

当 explain 与 SQL 一起使用时,MySQL 将显示来自优化器的有关语句执行计划的信息。即:MySQL 解释了它将如何处理该语句,包括有关如何连接表以及以何种顺序连接表等信息:

在这里插入图片描述
一般来说,我们需要重点关注 type、key、rows、extra

13.1 type

type 表示连接类型,查看索引执行情况的一个重要指标。以下性能从好到坏依次:system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

  • NULL:表示不用访问表,速度最快
  • system:这种类型要求数据库表中只有一条数据,是 const 类型的一个特例,一般情况下是不会出现的
  • const:通过一次索引就能找到数据,一般用于主键或唯一索引作为条件,这类扫描效率极高,速度非常快
  • eq_ref:常用于主键或唯一索引扫描,一般指使用主键的关联查询
  • ref : 常用于非主键和唯一索引扫描
  • ref_or_null:这种连接类型类似于 ref,区别在于 MySQL 会额外搜索包含 NULL 值的行
  • index_merge:使用了索引合并优化方法,查询使用了两个以上的索引
  • unique_subquery:类似于 eq_ref,条件用了 in 子查询
  • index_subquery:区别于 unique_subquery,用于非唯一索引,可以返回重复值
  • range:常用于范围查询,比如:between … and 或 In 等操作
  • index:全索引扫描
  • all:全表扫描

13.2 possible_keys

表示查询时能够使用到的索引(显示的是索引名称),只是可能用到的索引,而不是实际上用到的索引

13.3 key

该列表示实际用到的索引。一般配合 possible_keys 列一起看

13.4 rows

MySQL查询优化器会根据统计信息,估算 SQL 要查询到结果需要扫描多少行记录。原则上 rows 是越少效率越高,可以直观的了解到SQL效率高低

13.5 extra

该字段包含有关 MySQL 如何解析查询的其他信息,它一般会出现这几个值:

  • Using filesort:表示按文件排序,一般是在指定的排序和索引排序不一致的情况才会出现。一般见于 order by 语句。建议优化
  • Using temporary: 表示使用了临时表,性能特别差,需要重点优化。一般多见于 group by 语句,或者 union 语句
  • Using index :表示用了覆盖索引
  • Using where : 表示使用了 where 条件过滤,需要通过索引回表查询数据
  • Using index condition:MySQL5.6 之后新增的索引下推。在存储引擎层进行数据过滤,而不是在服务层过滤,利用索引现有的数据减少回表的数据
  • NULL:查询的列未被索引覆盖

总结:

extrawhere 条件select 的字段
nullwhere 筛选条件是索引的前导列查询的列未被索引覆盖
Using indexwhere 筛选条件是索引的前导列查询的列被索引覆盖
Using where; Using indexwhere 筛选条件是索引列之一但不是前导列或者where筛选条件是索引列前导列的一个范围查询的列被索引覆盖
Using where;where 筛选条件不是索引列-
Using where;where 筛选条件不是索引前导列、是索引列前导列的一个范围(>)查询列未被索引覆盖
Using index conditionwhere 索引列前导列的一个范围(<、between)查询列未被索引覆盖

两种排序的情况:

extra出现场景
Using filesortfilesort主要用于查询数据结果集的排序操作,首先MySQL会使用sort_buffer_size大小的内存进行排序,如果结果集超过了sort_buffer_size大小,会把这一个排序后的chunk转移到file上,最后使用多路归并排序完成所有数据的排序操作。
Using temporaryMySQL使用临时表保存临时的结构,以用于后续的处理,MySQL首先创建heap引擎的临时表,如果临时的数据过多,超过max_heap_table_size的大小,会自动把临时表转换成MyISAM引擎的表来使用。

filesort 只能应用在单个表上,如果有多个表的数据需要排序,那么MySQL会先使用using temporary保存临时数据,然后再在临时表上使用filesort进行排序,最后输出结果

13.6 select_type

select_type:表示查询的类型。

常用的值如下:

  • SIMPLE : 表示查询语句不包含子查询或 UNION
  • PRIMARY:表示此查询是最外层的查询
  • UNION:表示此查询是 UNION 的第二个或后续的查询
  • DEPENDENT UNION:UNION 中的第二个或后续的查询语句,使用了外面查询结果
  • UNION RESULT:UNION 的结果
  • SUBQUERY:SELECT 子查询语句
  • DEPENDENT SUBQUERY:SELECT子查询语句依赖外层查询的结果

最常见的查询类型是 SIMPLE,表示我们的查询没有子查询也没用到 UNION 查询

13.7 filtered

该列是一个百分比的值,通过查询条件最终查询记录行数和通过 type 字段扫描记录行数的百分比。简单点说,这个字段表示存储引擎返回的数据在经过过滤后,剩下满足条件的记录数量的比例

13.8 key_len

表示查询使用了索引的字节数量(可以判断是否全部使用了组合索引)

key_len的计算规则如下:

  1. 字符串类型:字符串长度跟字符集有关:latin1 = 1、gbk = 2、utf8 = 3、utf8mb4 = 4
    • char(n):n * 字符集长度
    • varchar(n):n * 字符集长度 + 2字节
  2. 数值类型
    • TINYINT:1个字节
    • SMALLINT:2个字节
    • MEDIUMINT:3个字节
    • INTFLOAT:4个字节
    • BIGINTDOUBLE:8个字节
  3. 时间类型
    • DATE:3个字节
    • TIMESTAMP:4个字节
    • DATETIME:8个字节
  4. 字段属性
    • NULL 属性占用1个字节,如果一个字段设置了 NOT NULL,则没有此项

3. profile 分析执行耗时

explain 只是看到 SQL 的预估执行计划如果要了解 SQL 真正的执行线程状态及消耗的时间,需要使用 profiling

开启 profiling 参数后,后续执行的 SQL 语句都会记录其资源开销,包括 IO,上下文切换,CPU,内存等等,我们可以根据这些开销进一步分析当前慢 SQL 的瓶颈再进一步进行优化

查看是否开启 profiling:

show variables like '%profil%'

开启 profiling :

set profiling=ON

使用 profiling :

show profiles

在这里插入图片描述

show profiles 会显示最近发给服务器的多条语句,条数由变量 profiling_history_size 定义,默认是 15。如果我们需要看单独某条 SQL 的分析,可以 show profile 查看最近一条 SQL 的分析,也可以使用 show profile for query id(其中id就是show profiles中的 QUERY_ID)查看具体一条的 SQL 语句分析:

在这里插入图片描述

4. Optimizer Trace 分析详情

profile 只能查看到 SQL 的执行耗时,但是无法看到 SQL 真正执行的过程信息,即不知道 MySQL 优化器是如何选择执行计划。这时候,我们可以使用 Optimizer Trace,它可以跟踪执行语句的解析优化执行的全过程

开启:

set optimizer_trace="enabled=on";

在这里插入图片描述

查看分析其执行树,会包括三个阶段:

  • join_preparation:准备阶段
  • join_optimization:分析阶段
  • join_execution:执行阶段

在这里插入图片描述

5. 确定问题并采用相应的措施

确认问题,就采取对应的措施。

  • 多数慢 SQL 都跟索引有关,比如不加索引,索引不生效、不合理等,这时候,我们可以优化索引
  • 我们还可以优化 SQL 语句,比如一些in元素过多问题(分批),深分页问题(基于上一次数据过滤等),进行时间分段查询
  • SQL 没办法很好优化,可以改用 ES 的方式,或者数仓
  • 如果单表数据量过大导致慢查询,则可以考虑分库分表
  • 如果数据库在刷脏页导致慢查询,考虑是否可以优化一些参数,跟 DBA 讨论优化方案
  • 如果存量数据量太大,考虑是否可以让部分数据归档

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

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

相关文章

微小奇迹的呵护:新生儿早产的温馨关怀

引言&#xff1a; 早产儿是生命的奇迹&#xff0c;但他们需要更多的呵护和关爱。对于家庭而言&#xff0c;正确的护理和关注对于早产儿的健康至关重要。本文将深入探讨早产儿的定义、早产的原因&#xff0c;以及家长在面对早产的时候应该采取的关键措施&#xff0c;为这些微小…

LeetCode刷题--- 优美的排列

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​​​​http://t.cs…

十大VSCODE 插件推荐2023

1、海鲸AI 插件链接&#xff1a;ChatGPT GPT-4 - 海鲸AI - Visual Studio Marketplace 包含了ChatGPT(3.5/4.0)等多个AI模型。可以实现代码优化&#xff0c;代码解读&#xff0c;代码bug修复等功能&#xff0c;反应迅捷&#xff0c;体验出色&#xff0c;是一个多功能的AI插件…

C++设计模式 #7 工厂方法(Factory Method)

“对象创建”模式 通过“对象创建”模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持创建的稳定。它是接口抽象之后的第一步工作。 动机 在软件系统中&#xff0c;经常面临着创…

.net core 表达式树Expression代码定义

表达式树是一种数据结构&#xff0c;它将代码表达式表示为可以在运行时修改和执行的层次结构。 我们通常在LINQ中使用表达式树来主动地将查询转换为针对各种数据源的可执行格式。翻译过程包括将查询表达式的声明性语法转换为一系列方法调用。 我们还可以在需要使用运行时代码…

云服务器ECS运维管理

目录 实时掌握CPU、内存使用情况 实时掌握存储的使用情况 定期对云服务器数据做好备份 定期检查云服务器的安全运行情况 要想保证云服务器长期稳定的使用&#xff0c;除了依靠阿里云&#xff08;云服务提供商&#xff09;的技术支持&#xff0c;自身必要的安全维护手段也是…

Opencv_CUDA实现推理图像前处理与后处理

Opencv_CUDA实现推理图像前处理与后处理 通过trt 或者 openvino部署深度学习算法时&#xff0c;往往会通过opencv的Mat及算法将图像转换为固定的格式作为输入openvino图像的前后处理后边将在单独的文章中写出今晚空闲搜了一些opencv_cuda的使用方法&#xff0c;在此总结一下前…

数据结构学习 Leetcode198 打家劫舍

动态结构 最长上升子序列 题目&#xff1a; 解法一&#xff1a; 思路&#xff1a; 状态&#xff1a;F[i]前i间房能偷到的最大金额。 转移方程&#xff1a; 偷和不偷取最大 如果不偷&#xff1a;F[i-1]如果偷&#xff1a;nums[i]F[i-2]如果偷就不能偷前一个&#xff0c;所…

【深度学习目标检测】十一、基于深度学习的电网绝缘子缺陷识别(python,目标检测,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…

牛客周赛 Round 22 解题报告 | 珂学家 | 思维构造 + 最小生成树

前言 整体评价 C题这个构造题挺好的&#xff0c;赛中把-1写成No, 直接整不会了&#xff0c;T_T. D题是一道很裸的最小生成树题&#xff0c;只需要一个小小的逆向思维&#xff0c;把删除操作转换为构建过程。 欢迎关注 珂朵莉 牛客周赛专栏 珂朵莉 牛客小白月赛专栏 A. 小红…

HTTP content-type内容类型的常见格式

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

概率论中的 50 个具有挑战性的问题 [第 6 部分]:Chuck-a-Luck

一、说明 我最近对与概率有关的问题产生了兴趣。我偶然读到了弗雷德里克莫斯特勒&#xff08;Frederick Mosteller&#xff09;的《概率论中的五十个具有挑战性的问题与解决方案》&#xff09;一书。我认为创建一个系列来讨论这些可能作为面试问题出现的迷人问题会很有趣。每篇…

OAuth2.0 四种授权方式讲解

一、OAuth2.0 的理解 OAuth2是一个开放的授权标准&#xff0c;允许第三方应用程序以安全可控的方式访问受保护的资源&#xff0c;而无需用户将用户名和密码信息与第三方应用程序共享。OAuth2被广泛应用于现代Web和移动应用程序开发中&#xff0c;可以简化应用程序与资源服务器之…

顺序表的基本操作(必学)

目录 线性表&#xff1a; 顺序表&#xff1a; 概念和结构&#xff1a; 动态顺序表常用操作实现&#xff1a; 头文件&#xff08;数组顺序表的声明&#xff09;&#xff1a; 各种基本操作总的声明&#xff1a; 顺序表的初始化&#xff1a; 顺序表的销毁 顺序表的打印 …

录屏软件哪个好用?全方位测评告诉你

随着数字技术的不断发展&#xff0c;录制屏幕的需求也越来越大。无论是制作教程、记录游戏过程&#xff0c;还是保存会议内容&#xff0c;一款好用的录屏软件都能让用户事半功倍。可是录屏软件哪个好用呢&#xff1f;在本文中&#xff0c;我们将介绍三款流行的录屏软件。通过详…

std::string在 Windows MSVC和Linux Gcc 中capacity容量扩容策略的分析和对比

1、capacity()作用 在std::string中&#xff0c;capacity()为当前string占用内存字符的长度&#xff0c;表示当前string的容量&#xff0c;可以理解为一个预分配制度&#xff0c;如果当前的string不断进行扩展操作&#xff0c;则不需要每次都进行内存上的分配&#xff0c;提高程…

iconify图标集离线使用方案简介

1.需求描述 前端项目&#xff0c;技术栈使用Vue3Element Plus&#xff0c;参考了ruoyi-vue-pro项目与vue-element-plus-admin项目&#xff0c;封装了一个Icon组件&#xff0c;图标使用的是iconify,项目部署在内网环境&#xff0c;不能连接互联网&#xff0c;需要部署一套iconi…

MAC鼠标中键的使用

MAC鼠标没有鼠标中键&#xff0c;于是在一些场景中用起来非常麻烦&#xff0c;这里介绍几种键盘快捷键鼠标左键实现中键功能的例子&#xff1a; 1&#xff09;在sublime text 或者pycharm等一些文本编辑器或IDE中实现中键修改一列数据中特定位置的值 FNOPT左键另外还有C4D&…

生存分析序章1——解析生存分析:探寻时间与事件的奥秘

写在开头 生存分析&#xff0c;作为统计学和生物学交汇的领域&#xff0c;旨在探究时间与事件之间的奥秘。这一领域的深入研究不仅在医学和生物学领域有着广泛的应用&#xff0c;同时在数据分析和数据挖掘中也发挥着关键作用。 1 基本概念 1.1 什么是生存分析 生存分析&…

STM32独立看门狗和窗口看门狗的区别

独立看门狗&#xff1a; 本质上是一个定时器&#xff0c;这个定时器有一个输出端&#xff0c;可以输出复位信号。 该定时器是一个 12 位的递减计数器&#xff0c;当计数器的值减到 0 的时候&#xff0c;就会产生一个复位信号。如果在计数没减到 0 之前&#xff0c;重置计数器的…