MySQL慢查询(上):你知道为啥会慢么?

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 在过去的半年时间里,研发团队内部尝试抓了一波儿慢查询SQL跟进处理率。发现有些同学对于慢查询处理的思路就是看看有没有用到索引,没有用到就试图加一个,实在不行就甩锅给这种情况是历史设计问题或者自行判定为用户特殊操作下触发的小概率事件,随即便申请豁免掉... 其实问题没有根本上解决。

发现的一些问题


问题1


在过去的半年时间里,研发团队内部尝试抓了一波儿慢查询SQL跟进处理率。发现有些同学对于慢查询处理的思路就是看看有没有用到索引,没有用到就试图加一个,实在不行就甩锅给这种情况是历史设计问题或者自行判定为用户特殊操作下触发的小概率事件,随即便申请豁免掉... 其实问题没有根本上解决。


问题2


还有就是网络上经常可以看到一些类似这样的文章:


“慢SQL性能优化大全”


“慢SQL性能优化看这篇就够了”...  


其实内容大同小异,要么建议加索引,要么建议重写SQL....


怎么说呢?知识点是对的,但不全面,这个很容易误导新同学,哈哈哈。


本文初衷


在业务项目发展过程中,我们常常会面对要处理 MySQL 慢查询问题,那我们应该如何分析解决问题呢?


部分同学在处理MySQL慢查询时候主要思路是加索引来解决,确实加索引是一个很好的解决问题的手段,但不是全部。既然慢查询作为问题,那就需要明确问题发生原因,和解决问题路径分析, 授人以鱼不如授人以渔,让我们一起来解锁 🔓 下MySQL处理慢查询的正确姿势。


本文计划主要让大家搞明白查询SQL为什么会变慢废话不多说,直接开干~


写在前面


在业务项目发展过程中,我们常常会面对要处理 MySQL 慢查询问题,那我们应该如何分析解决问题呢?


部分同学在处理MySQL慢查询时候主要思路是加索引来解决,确实加索引是一个很好的解决问题的手段,但不是全部。既然慢查询是问题,那就需要明确问题发生原因,和解决问题路径分析。我们一起来get下MySQL慢查询的正确姿势。


一、查询SQL执行到底经历了什么?


首先需要明确:一个查询SQL的执行到底经历了什么?


微信图片_20220608095532.png


数据库执行SQL的大致流程如下:


  • 建立与MySQL服务器连接(基础)


  • 客户端发送查询SQL到数据库,数据库验证是否有执行的权限


  • MySQL服务器先检查查询缓存,如果命中了缓存,则立即返回存储在缓存中的结果,否则继续流转;


  • MySQL服务器语法解析器,进行词法与语法分析,预处理


  • 流转至查询优化器生成执行计划


  • 根据生成的执行计划,调用存储引擎暴露的API来执行查询


  • 将查询执行结果返回给客户端


  • 关闭MySQL连接

具体执行过程可能会因MySQL服务器具体配置和执行场景有一些差异。


1)如未开启应用查询缓存,则直接忽略查询缓存的检查;


2)执行过程中,如同时对于被扫描的行可能加锁,同时也可能会被其他sql阻塞


二、查询SQL为什么会慢?


我们可以把查询SQL执行看做是一个任务的话,那它是由一些列子任务组成的,每个子任务都存在一定的时间消耗。通常情况下,导致慢查询最根本的问题就是需要访问的数据太多,导致查询不可避免的需要筛选大量的数据


面对慢查询,我们需要注意以下两点:


1)查询了过多不需要的数据


2)扫描了额外的记录


2.1 查询了过多不需要的数据


MySQL并不是只返回需要的数据,实际上会返回全部结果集再进行计算。


尤其是多表关联查询 select * 的情况,我们是不是真的需要全部的列呢?如果不是,那我们直接指定对应字段就好了。


例如我们要查询用户关联订单下的商品信息,如下所示:


SELECT *
FROM users
  LEFT JOIN orders ON orders.user_id = users.user_id
  LEFT JOIN goods ON goods.good_id = orders.good_id
WHERE users.name = 'zhangsan';


这将返回三个表的全部数据列,可以调整为仅取需要的列:


SELECT goods.title, goods.description
FROM users
  LEFT JOIN orders ON orders.user_id = users.user_id
  LEFT JOIN goods ON goods.good_id = orders.good_id
WHERE users.name = 'zhangsan';


取出全部列,会让优化器无法完成索引覆盖扫描这类优化,还会为服务器带来额外的I/O、内存和CPU的消耗。


2.2 扫描了额外的记录


此种情况大部分属于索引应用不当造成的(包括:该建的索引没有建,或者未应用到最佳索引)。


示例表结构如下:


CREATE TABLE `test_table` (
  `name` varchar(32) DEFAULT NULL,
  `desc` varchar(32) DEFAULT NULL,
  `age` int(16) DEFAULT NULL,
  `id` bigint(11) DEFAULT NULL,
  KEY `idx_age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


存在索引 `idx_age` 的情况下,查询执行计划如下:


EXPLAIN SELECT * FROM test_table WHERE age = 10;


微信图片_20220608095801.png


预估访问1行数据即可命中数据,如删除有效索引 `idx_age` 后则会变成全表扫描(ALL),预估需要扫描121524条记录才能完成这个查询,如下图所示:


微信图片_20220608095805.png


小结


根据梳理 MySQL中的 SQL执行过程我们发现,任何流程的执行都存在其执行环境和规则,其实产生慢SQL的本质是:我们没有按照数据库的要求方式来执行SQL

主要导致慢查询最根本的问题就是需要访问的数据太多,导致查询不可避免的需要筛选大量的数据。


限于文章篇幅,同时为了大家更好的阅读体验,后面会连续产出系列文章:


MySQL慢查询(中)


   主要内容包括 如何定位慢查询问题几种实用解决方案


MySQL慢查询(


   主要内容包括 高性能查询难题优化内容点总结

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
SQL 监控 关系型数据库
深入理解MySQL日志:通用查询、慢查询和错误日志详解
深入理解MySQL日志:通用查询、慢查询和错误日志详解
1014 0
|
10月前
|
关系型数据库 MySQL 索引
mysql之开启慢查询日志
mysql之开启慢查询日志
|
10月前
|
SQL 监控 关系型数据库
【MYSQL高级】Mysql找出执行慢的SQL【慢查询日志使用与分析】
【MYSQL高级】Mysql找出执行慢的SQL【慢查询日志使用与分析】
826 0
|
3月前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
188 1
|
7天前
|
SQL 关系型数据库 MySQL
MySQL——开启慢查询
MySQL——开启慢查询
12 0
|
2月前
|
SQL 缓存 关系型数据库
MySQL慢查询优化实践问答
MySQL慢查询优化实践问答
|
2月前
|
SQL 关系型数据库 MySQL
MySQL数据库——索引(3)-索引语法(创建索引、查看索引、删除索引、案例演示),SQL性能分析(SQL执行频率,慢查询日志)
MySQL数据库——索引(3)-索引语法(创建索引、查看索引、删除索引、案例演示),SQL性能分析(SQL执行频率,慢查询日志)
33 2
|
2月前
|
SQL 监控 关系型数据库
MySQL慢查询日志配置指南:发现性能瓶颈,提升数据库效率
MySQL慢查询日志配置指南:发现性能瓶颈,提升数据库效率
189 0
|
3月前
|
SQL 监控 关系型数据库
【MySQL学习】MySQL的慢查询日志和错误日志
【MySQL学习】MySQL的慢查询日志和错误日志
|
3月前
|
SQL 关系型数据库 MySQL
mysql5.7 慢查询配置 查看sql语句执行时间
mysql5.7 慢查询配置 查看sql语句执行时间
61 1