【Java 开发日记】我们来说一下 MySQL 的慢查询日志

【Java 开发日记】我们来说一下 MySQL 的慢查询日志

目录

一、什么是慢查询日志

二、核心作用

三、配置参数详解

四、开启和配置

1. 临时开启(重启失效)

2. 永久开启(修改配置文件)

五、慢查询日志格式分析

典型日志条目:

关键字段解释:

六、慢查询分析工具

1. mysqldumpslow(MySQL 自带)

2. pt-query-digest(Percona Toolkit)

3. mysqlslow(第三方工具)

七、慢查询日志表模式

启用表模式存储:

表结构:

八、最佳实践和优化建议

1. 阈值设置建议

2. 日志轮转配置

3. 定期分析计划

九、性能监控和告警

1. 监控慢查询数量

2. 慢查询告警脚本

十、注意事项

面试回答


一、什么是慢查询日志

慢查询日志(Slow Query Log) 是 MySQL 内置的一种日志功能,用于记录执行时间超过指定阈值的 SQL 语句。这是优化数据库性能的重要工具。

二、核心作用

  1. 性能诊断:找出执行效率低的 SQL 语句
  2. 瓶颈定位:分析查询为什么慢(全表扫描、索引缺失等)
  3. 优化依据:为 SQL 优化和索引调整提供数据支持

三、配置参数详解

-- 查看所有慢查询相关参数 SHOW VARIABLES LIKE '%slow%'; SHOW VARIABLES LIKE '%long_query_time%'; -- 主要配置参数: -- slow_query_log = OFF/ON # 是否开启慢查询日志 -- slow_query_log_file = /path/name # 日志文件路径 -- long_query_time = 10 # 阈值(秒),默认10秒 -- min_examined_row_limit = 0 # 最少检查行数阈值 -- log_queries_not_using_indexes = OFF # 是否记录未使用索引的查询 -- log_slow_admin_statements = OFF # 是否记录管理语句 -- log_output = FILE/TABLE/NONE # 输出方式

四、开启和配置

1. 临时开启(重启失效)
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2; -- 设为2秒 SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log'; SET GLOBAL log_queries_not_using_indexes = 'ON';
2. 永久开启(修改配置文件)
# my.cnf 或 my.ini [mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 log_queries_not_using_indexes = 1 log_output = FILE

五、慢查询日志格式分析

典型日志条目:
# Time: 2024-01-01T10:00:00.123456Z # User@Host: root[root] @ localhost [] Id: 5 # Query_time: 5.123456 Lock_time: 0.001000 Rows_sent: 10 Rows_examined: 1000000 SET timestamp=1672560000; SELECT * FROM users WHERE last_name LIKE '%smith%' ORDER BY create_time DESC;
关键字段解释:
  • Query_time:查询执行总时间
  • Lock_time:锁定时间
  • Rows_sent:返回给客户端的行数
  • Rows_examined:扫描的行数
  • Rows_affected:影响的行数(UPDATE/DELETE/INSERT)

六、慢查询分析工具

1. mysqldumpslow(MySQL 自带)
# 按查询时间排序 mysqldumpslow -s t /var/log/mysql/slow.log # 按锁时间排序 mysqldumpslow -s l /var/log/mysql/slow.log # 按执行次数排序 mysqldumpslow -s c /var/log/mysql/slow.log # 显示前10条最慢的查询 mysqldumpslow -t 10 /var/log/mysql/slow.log # 分析特定用户的慢查询 mysqldumpslow -a -g "root" /var/log/mysql/slow.log
2. pt-query-digest(Percona Toolkit)
# 分析慢查询日志 pt-query-digest /var/log/mysql/slow.log # 分析最近12小时的慢查询 pt-query-digest --since=12h /var/log/mysql/slow.log # 输出到文件 pt-query-digest /var/log/mysql/slow.log > slow_report.txt
3. mysqlslow(第三方工具)
mysqlslow /var/log/mysql/slow.log

七、慢查询日志表模式

启用表模式存储:
SET GLOBAL log_output = 'TABLE'; SET GLOBAL slow_query_log = 'ON'; -- 查询慢查询日志 SELECT * FROM mysql.slow_log;
表结构:
SHOW CREATE TABLE mysql.slow_log; -- 主要字段: -- start_time: 查询开始时间 -- query_time: 查询耗时 -- lock_time: 锁定时间 -- rows_sent: 返回行数 -- rows_examined: 检查行数 -- sql_text: SQL语句 -- user_host: 用户和主机信息

八、最佳实践和优化建议

1. 阈值设置建议
-- 生产环境建议 SET GLOBAL long_query_time = 2; -- 2秒阈值 -- 开发/测试环境可以更严格 SET GLOBAL long_query_time = 0.5; -- 500毫秒 -- 微秒级精度(MySQL 5.7+) SET GLOBAL long_query_time = 0.1; -- 100毫秒
2. 日志轮转配置
# 使用 logrotate /var/log/mysql/slow.log { daily rotate 30 missingok compress delaycompress notifempty create 640 mysql mysql postrotate mysqladmin flush-logs endscript }
3. 定期分析计划
# 每日分析脚本示例 #!/bin/bash DATE=$(date +%Y%m%d) pt-query-digest /var/log/mysql/slow.log > /var/log/mysql/slow_report_${DATE}.txt # 清空日志文件(先备份) cp /var/log/mysql/slow.log /var/log/mysql/slow.log.${DATE} echo "" > /var/log/mysql/slow.log

九、性能监控和告警

1. 监控慢查询数量
-- 监控每分钟的慢查询数量 SHOW GLOBAL STATUS LIKE 'Slow_queries'; -- 查看当前慢查询 SHOW PROCESSLIST;
2. 慢查询告警脚本
#!/bin/bash SLOW_COUNT=$(mysql -e "SHOW GLOBAL STATUS LIKE 'Slow_queries'" | grep Slow_queries | awk '{print $2}') THRESHOLD=100 if [ $SLOW_COUNT -gt $THRESHOLD ]; then echo "警告:慢查询数量异常!当前数量: $SLOW_COUNT" | mail -s "MySQL慢查询告警" [email protected] fi

十、注意事项

  1. 性能影响:开启慢查询日志会有约1-3%的性能开销
  2. 磁盘空间:定期清理,避免日志文件过大
  3. 敏感信息:日志可能包含敏感数据,需妥善保管
  4. 生产环境:建议设置合理的阈值,避免记录过多无关查询
  5. 版本差异:MySQL 5.7+ 支持微秒级精度,之前版本只到秒

面试回答

简单来说,慢查询日志就像是 MySQL 的一个‘病历本’。它会自动记录下来所有执行时间超过某个阈值的 SQL 语句。这样我们开发或者 DBA 就能知道,哪些查询是‘慢’的、有问题的,然后去针对性地优化。

在实际工作中,我主要会关注和操作这么几个方面:

第一,怎么开启和设置。
慢查询日志默认是关闭的,因为它会有一点磁盘 I/O 的开销。我们需要在 MySQL 配置文件(比如 my.cnf)里设置几个核心参数:

  1. slow_query_log = ON:打开开关。
  2. slow_query_log_file:指定这个‘病历本’文件存哪里。
  3. long_query_time:这是最重要的一个阈值,单位是秒。比如设为 1,就意味着执行超过 1 秒的 SQL 才会被记录。这个值可以根据系统性能要求来调整。
  4. log_queries_not_using_indexes:这个我也经常会打开。它会记录那些没有使用索引的查询,即使它执行得很快。这能帮我们发现潜在的设计问题。

第二,怎么看这个日志。
日志是文本格式,可以直接看,但不太直观。我常用的方法是:

  1. 用 MySQL 自带的 mysqldumpslow 工具。这个命令行工具可以对日志进行汇总、排序,比如我们可以用 mysqldumpslow -t 10 -s t 来找出耗时最长的前 10 条 SQL,一目了然。
  2. 对于更复杂的分析,我会用 Percona 公司开的pt-query-digest 工具。它功能更强大,能给出非常详细的报告,比如每个 SQL 的响应时间占比、执行次数、锁时间等,能帮我快速定位最需要优化的‘瓶颈’ SQL。

第三,也是最重要的,找到慢 SQL 后怎么办。
光找到没用,关键是要优化。我一般的排查思路是:

  1. 拿到这条慢 SQL,先explain 命令去看它的执行计划。这是标准动作。我会重点看:
    • 有没有用到索引(key 字段)。
    • 扫描了多少行(rows 字段)。
    • 查询类型是不是全表扫描(type 字段,如果是 ALL 就不好了)。
  1. 根据explain的结果,常见的优化手段就是:
    • 加索引:这是最有效的办法之一,检查 WHEREORDER BYJOIN 的字段。
    • 优化 SQL 本身:比如避免 SELECT *,检查是否有复杂的子查询能不能改写为 JOIN,或者分页查询在大偏移量时有没有优化空间。
    • 看看是不是数据库参数问题,比如缓冲池大小是不是不合理。

最后,我的一点实践经验是:慢查询日志在测试环境和生产环境都很有用。在项目上线前,我们会开启它来提前发现一些性能问题。在生产环境,我们会长期开启,但会设置一个合理的 long_query_time(比如从 2 秒开始),并定期归档和分析日志,把它作为性能监控和容量规划的一个重要依据。

如果小假的内容对你有帮助,请点赞评论收藏。创作不易,大家的支持就是我坚持下去的动力!

Read more

Java外功基础(1)——Spring Web MVC

Java外功基础(1)——Spring Web MVC

1.前置知识 1.1 Tomcat 定义:Tomcat是一个开源的轻量级Web(Http)服务器和Servlet容器。它实现了Java Servlet等Java EE规范的核心功能,常用于部署和运行Java Web应用程序 。换言之,Tomcat就是一个严格遵循Servlet规范开发出来的、可以独立安装和运行的Java Web服务器/Servlet容器核心功能:Servlet容器:支持Servlet的执行,处理HTTP请求和响应Web服务器:提供静态资源(如HTML)的访问能力,支持基本的HTTP服务安装与版本对应: tomcat官网:Apache Tomcat®目录结构:bin:存放可执行文件,如startup.batconf:存放配置文件lib:存放Tomcat运行所需的jar文件logs:存储日志文件temp:存放临时文件,如上传的文件或缓存数据webapps:默认web应用部署目录work:服务器的工作目录,存放运行时生成的临时文件(编译文件) 1.2 Servlet 1.2.1 定义

By Ne0inhk

区块链从入门到精通(Java 实战版)

区块链从入门到精通(Java 实战版) 面向完全小白的一份“讲人话”教程,重点放在:到底是什么、有啥用、怎么用 Java 写点真正能跑的代码。 1. 区块链到底是个啥?(用大白话讲清楚) * 先不讲技术,先讲故事: * 想象有一个村子,大家天天记账:谁欠谁钱,谁给谁打工,谁给谁送了鸡蛋。 * 以前只有村长一本账本,大家必须相信村长不作弊。 * 有一天,村长和别人串通,把账改了,你根本没法证明。 * 区块链 = 把账本复制一份给全村所有人,每一笔账都要全村人一起确认,任何人想偷偷改账,几乎不可能。 * 用更正式一点的话: * 区块链(Blockchain) 是一种: * 分布式(大家一起维护) * 只能追加、很难篡改的账本系统 * 用密码学(哈希、签名)保证数据安全和不可抵赖 * 用共识算法保证“大家对账本内容达成一致” * 你可以先这么理解: 区块链 = 分布式数据库

By Ne0inhk
【LeetCode必刷好题】:Java顺序表实现杨辉三角

【LeetCode必刷好题】:Java顺序表实现杨辉三角

🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:Java.数据结构 【前言】 杨辉三角作为经典的数学与编程结合案例,是理解二维数组和动态列表操作的绝佳素材。本文将带你从逻辑拆解、问题分析、优化方向等角度进行详细解析,带你彻底掌握杨辉三角的实现精髓。 文章目录: * 一、杨辉三角思路分析 * 二、代码实现 * 三、总结 一、杨辉三角思路分析 杨辉三角每一行数字都是上一行两个相邻数字之和 思路分析: 创建一个二维列表List<List<Integer>>,储存整个三角外层循环控制行数 i,0~numRows内层循环是列数 j,小于 i每一行第一个和最后一个是1中间元素通过上一行相邻元素加得 二、代码实现 publicclassTest{publicList<List<Integer&

By Ne0inhk
使用Java基于Geotools的SLD文件编程式创建与磁盘生成实战

使用Java基于Geotools的SLD文件编程式创建与磁盘生成实战

前言         在地理信息系统(GIS)领域,地图的可视化呈现至关重要,而样式定义语言(SLD)文件为地图元素的样式配置提供了强大的支持。SLD 能够精确地定义地图图层中各类要素(如点、线、面、文本等)的颜色、大小、填充图案、边框样式等外观特征,使得地图不仅能够传递空间数据信息,还能以符合用户需求和业务场景的美观、直观形式展示出来。         Java 作为一种广泛应用于企业级开发的编程语言,在 GIS 软件开发中也占据着重要地位。Geotools 作为开源的 Java GIS 工具库,为地理数据处理、地图渲染等提供了丰富的功能组件。借助 Geotools,开发者可以便捷地操作空间数据,并基于其丰富的 API 进行地图应用的定制开发。在实际项目中,常常需要根据不同的业务逻辑、数据状态或用户配置动态生成 SLD 文件,以实现地图样式的灵活调整与个性化定制。例如,一个环境监测系统可能需要根据实时监测数据的污染程度动态改变地图上对应区域的填充颜色,或者一个交通规划应用需要依据交通流量状况动态调整道路线条的宽度和颜色深浅等。         本文将深入探讨如何使用 Java

By Ne0inhk