MySQL慢查询排查和优化的详细步骤教学

 更新时间:2026年03月25日 11:32:32   作者:Change_Your  
慢SQL的排查和优化是数据库性能调优的关键环节,尤其是在高并发环境下,慢 SQL 可能会导致性能瓶颈,影响应用响应速度,以下是关于如何排查和优化慢 SQL 的详细步骤,感兴趣的小伙伴可以跟随小编一起学习一下

慢 SQL 的排查和优化是数据库性能调优的关键环节,尤其是在高并发环境下,慢 SQL 可能会导致性能瓶颈,影响应用响应速度。以下是关于如何排查和优化慢 SQL 的详细步骤。

一、如何排查慢 SQL

1.开启慢查询日志

MySQL 提供了慢查询日志功能,可以帮助我们识别执行时间较长的 SQL 查询。

启用慢查询日志:

SET GLOBAL slow_query_log = 'ON';  -- 开启慢查询日志
SET GLOBAL slow_query_log_file = '/path/to/your/slow_query.log';  -- 设置日志文件路径
SET GLOBAL long_query_time = 1;  -- 设置记录慢查询的阈值,单位秒(1秒以上的查询会被记录)

查看慢查询日志内容:

查看日志文件,通常包含查询时间、SQL 语句等信息。

cat /path/to/your/slow_query.log

2.使用EXPLAIN语法分析 SQL 执行计划

EXPLAIN 可以展示 MySQL 如何执行一个查询,它可以帮助你分析查询性能瓶颈。

EXPLAIN SELECT * FROM your_table WHERE condition;

EXPLAIN 的结果列包括:

  • id:查询的标识符。
  • select_type:查询的类型(如 SIMPLEPRIMARYUNION)。
  • table:查询涉及的表。
  • type:连接类型,表示查询的访问方式(如 ALLindexrange)。
  • key:使用的索引。
  • rows:MySQL 执行查询时扫描的行数。
  • Extra:额外的信息,提示是否使用了文件排序(Using filesort)或临时表(Using temporary)等。

3.使用SHOW PROCESSLIST查看当前查询

查看当前正在执行的查询,以便了解哪些查询可能会导致系统负载过高。

SHOW PROCESSLIST;

会返回正在执行的查询、线程 ID、状态等信息,特别是 StateInfo 字段,能帮助判断哪些查询正在消耗时间。

4.查看数据库状态和性能指标

查看数据库的运行状态和各项性能指标,比如缓冲池的使用情况、I/O 性能等,可以帮助判断慢查询的原因。

SHOW STATUS LIKE 'Innodb_buffer_pool%';
SHOW STATUS LIKE 'Qcache%';
SHOW STATUS LIKE 'Handler_read%';

这些命令能够给出关于缓存、I/O、查询缓存的详细信息。

二、慢 SQL 优化方法

1.分析和优化查询语句

(1)避免全表扫描

全表扫描通常是查询缓慢的原因之一。通过合理的索引设计,确保查询尽量通过索引来执行。

  • 例如,避免使用 SELECT *,只选择需要的字段。
  • 确保 WHERE 子句中的条件列有索引。

(2)避免使用不必要的JOIN

对于查询中涉及多个表时,减少 JOIN 的次数和复杂度。尤其要注意,使用不合理的 JOIN 会导致大量的数据中间结果集,影响查询性能。

  • 避免使用多次 JOIN:如果多个表之间没有必要联接,就不必使用 JOIN
  • 使用适当的连接顺序:在 JOIN 时,优先连接那些数据量小、过滤条件明确的表。

(3)避免在查询中使用函数和表达式

WHERE 条件中对列进行函数操作(如 YEAR(date)LOWER(name) 等)会导致 MySQL 无法利用索引。

例如:

SELECT * FROM orders WHERE YEAR(order_date) = 2025;

如果在 order_date 上没有合适的索引,这样的查询会导致全表扫描。

2.合理使用索引

(1)索引优化

  • 确保常用的查询字段(尤其是 WHERE 子句、JOIN 条件、ORDER BYGROUP BY 字段)都有适当的索引。
  • 对于范围查询(如 BETWEEN>、<)字段,应该确保索引的顺序符合最左前缀原则。

(2)避免索引失效

  • 避免对索引列做计算或函数操作,如 WHERE YEAR(date) = 2025
  • 使用覆盖索引,当查询的字段都包含在索引中时,索引就可以返回查询结果,无需回表。
CREATE INDEX idx_name ON users(name, email);

如果查询时仅涉及 nameemail 字段,索引就可以直接返回结果。

(3)减少索引的数量

过多的索引会影响写入性能,尤其是在 INSERTUPDATEDELETE 操作时。应根据查询的频率和类型合理选择索引。

3.合理使用数据库缓存

(1)调整InnoDB缓冲池大小

InnoDB 存储引擎使用缓冲池缓存数据和索引。适当增大缓冲池的大小可以减少磁盘 I/O,提高查询性能。

SET GLOBAL innodb_buffer_pool_size = <size>;

(2)使用查询缓存

虽然在 MySQL 5.7 后已弃用查询缓存,但在适用的场景下,开启查询缓存仍能提高查询性能。

SET GLOBAL query_cache_size = <size>;

(3)调整sort_buffer_size和read_buffer_size

这些参数影响排序操作和全表扫描操作的内存使用。适当增大这些值,可以减少磁盘 I/O,提高查询效率。

SET GLOBAL sort_buffer_size = <size>;
SET GLOBAL read_buffer_size = <size>;

4.优化表结构和分区

(1)表分区

当表非常大时,使用分区可以提高查询性能。表分区会根据某个列的值将数据分到不同的物理存储区域,这样可以减少每次查询时的数据扫描量。

(2)避免表的过度设计

例如,避免在同一个表中存储过多的历史数据,定期归档过期的数据。对于长期不更新的数据,可以使用更为高效的存储方式(例如将历史数据迁移到冷数据存储)。

5.分页查询优化

分页查询通常会出现性能问题,尤其是当页数很大时。优化方法包括:

  • 使用 LIMITOFFSET 时,确保有合适的索引,避免大范围的全表扫描。
  • 使用 WHERE 子句限制记录范围,如按时间戳或 ID 排序,避免使用不索引的字段进行分页。
SELECT * FROM orders WHERE order_date >= '2025-01-01' LIMIT 100 OFFSET 1000;

6.减少网络带宽消耗

对于返回大量数据的查询,减少返回的数据量也是一个优化点。只查询必要的字段,避免 SELECT *

7.考虑读写分离

对于数据库的高并发访问,读写分离可以通过将读操作和写操作分配到不同的数据库实例,来分担数据库负载,从而优化查询性能。

三、背诵版

慢 SQL 排查:

  • 开启慢查询日志SET GLOBAL slow_query_log = 'ON';
  • 使用 EXPLAIN 分析执行计划:查看是否有全表扫描、索引扫描等。
  • SHOW PROCESSLIST 查看当前执行的查询:找到耗时较长的查询。
  • 查看 MySQL 状态信息:如 SHOW STATUS LIKE 'Innodb_buffer_pool%',分析缓存和 I/O 使用情况。

慢 SQL 优化方法:

优化查询语句

  • 避免全表扫描。
  • 合理使用 JOIN 和子查询。
  • 不要在查询条件中使用函数或表达式。

优化索引

  • 为常用查询字段添加合适的索引。
  • 使用覆盖索引避免回表。
  • 减少不必要的索引。

缓存优化:调整 InnoDB 缓冲池大小,合理使用查询缓存。

分页查询优化:避免大页数的 OFFSET 分页,限制查询范围。

读写分离:通过数据库主从分离,减轻数据库压力。

到此这篇关于MySQL慢查询排查和优化的详细步骤教学的文章就介绍到这了,更多相关MySQL慢查询优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MYSQL半同步配置思路

    MYSQL半同步配置思路

    在默认设置下,MySQL使用异步复制,主库发送binlog后不等待从库确认,可能导致数据不一致或丢失,半同步复制则在主库更新数据后先等待从库确认同步完成,本文给大家介绍MYSQL半同步配置,感兴趣的朋友一起看看吧
    2023-09-09
  • Navicat for MySQL的使用教程详解

    Navicat for MySQL的使用教程详解

    本文给大家介绍Navicat for MySQL的使用教程,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习下吧
    2021-05-05
  • 解读MySQL的客户端和服务端协议

    解读MySQL的客户端和服务端协议

    这篇文章主要介绍了MySQL的客户端和服务端协议的相关资料,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下
    2021-05-05
  • MySQL 实现树的遍历详解及简单实现示例

    MySQL 实现树的遍历详解及简单实现示例

    这篇文章主要介绍了MySQL 实现树的遍历详解及简单实现示例的相关资料,这里提供了示例代码及测试结果,需要的朋友可以参考下
    2017-01-01
  • MySQL 加密/压缩函数

    MySQL 加密/压缩函数

    在MySQL中,加密和压缩函数返回二进制串。对其中的许多函数而言,结果可能包含任意的字节值,如果想存储这些结果,你应该使用一个具有varbinary或者blob二进制串数据类型的列,这可避免潜在的删除尾部空白问题或者字符集转换问题。
    2009-12-12
  • MSQL中DATETIME或TIMESTAMP的区别小结

    MSQL中DATETIME或TIMESTAMP的区别小结

    MySQL中的 DATETIME 和 TIMESTAMP 类型都用于存储日期和时间信息,本文主要介绍了MSQL中DATETIME或TIMESTAMP的区别小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • MySql各种查询方式详解

    MySql各种查询方式详解

    如果是做数据分析,MySQL里面最重要、最常用的就是数据查询,数据查询不只是简单查询数据库中存储的数据,还要根据需求对数据进行筛选、聚合,以及确定数据以什么样的格式进行显示。MySQL提供了强大、灵活的语句和函数来实现查询的操作
    2022-07-07
  • MySQL递归sql语句WITH表达式实现方法代码

    MySQL递归sql语句WITH表达式实现方法代码

    SQL递归查询语句是指通过递归方式对数据进行查询的语句,下面这篇文章主要给大家介绍了关于MySQL递归sql语句WITH表达式实现的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • mysql更改引擎(InnoDB,MyISAM)的方法

    mysql更改引擎(InnoDB,MyISAM)的方法

    这篇文章主要介绍了mysql更改引擎(InnoDB,MyISAM)的方法,实例讲述了比较常见的几种更改引擎的方法,非常具有实用价值,需要的朋友可以参考下
    2014-11-11
  • MySQL 机器重启后gtid_executed初始化流程解析

    MySQL 机器重启后gtid_executed初始化流程解析

    文章介绍了MySQL中gtid_executed和gtid_purged的初始化过程,包括从mysql.gtid_executed表加载、扫描binlog文件以验证和补充、最终计算并合并这两个集合,以及gtid_purged的计算方法,感兴趣的朋友跟随小编一起看看吧
    2025-12-12

最新评论