如何在 MySQL 中实现慢查询监控

如何在 MySQL 中实现慢查询监控

在数据库管理中,慢查询是性能优化的重要一环,特别是在处理大量数据或复杂查询时。通过监控慢查询,我们可以找到性能瓶颈并加以优化。本文将详细介绍如何在 MySQL 中开启慢查询日志,设置查询阈值,并如何使用查询日志来监控慢查询。


文章目录

  • [如何在 MySQL 中实现慢查询监控](#如何在 MySQL 中实现慢查询监控)
    • [1. 开启慢查询日志](#1. 开启慢查询日志)
    • [2. 设置慢查询阈值](#2. 设置慢查询阈值)
    • [3. 设置日志输出方式](#3. 设置日志输出方式)
    • [4. 查询慢查询日志](#4. 查询慢查询日志)
    • [5. 优化慢查询](#5. 优化慢查询)
    • [6. 日常维护与监控](#6. 日常维护与监控)
    • [🔍 慢查询日志表分析SQL集合](#🔍 慢查询日志表分析SQL集合)
      • [1️⃣ 查看最慢的TOP查询](#1️⃣ 查看最慢的TOP查询)
      • [2️⃣ 统计慢查询概况](#2️⃣ 统计慢查询概况)
      • [3️⃣ 按数据库分组分析](#3️⃣ 按数据库分组分析)
      • [4️⃣ 找出相似SQL(按模式分组)](#4️⃣ 找出相似SQL(按模式分组))
      • [5️⃣ 按时间段分析](#5️⃣ 按时间段分析)
      • [6️⃣ 找出扫描行数最多的查询](#6️⃣ 找出扫描行数最多的查询)
      • [7️⃣ 按用户分析](#7️⃣ 按用户分析)
      • [8️⃣ 综合分析视图](#8️⃣ 综合分析视图)
    • 总结

1. 开启慢查询日志

首先,我们需要开启 MySQL 的慢查询日志功能。慢查询日志能够记录执行时间超过指定阈值的查询。你可以使用以下 SQL 命令来开启慢查询日志:

sql 复制代码
SET GLOBAL slow_query_log = 'ON';

该命令会启用慢查询日志功能,并开始记录那些执行时间超过指定阈值的查询。注意,GLOBAL 表示修改的是全局设置,这意味着此设置在 MySQL 重启之前会一直有效。

2. 设置慢查询阈值

慢查询日志的一个关键设置是 查询阈值,也就是说,只有执行时间超过这个阈值的查询才会被记录。可以通过 long_query_time 参数设置该阈值,单位是秒。如果你希望记录那些执行时间大于0.01秒的查询,可以使用以下命令:

sql 复制代码
SET GLOBAL long_query_time = 0.01;

如果将 long_query_time 设置为 0.01,则表示查询执行时间超过 0.01 秒的查询都会被记录到慢查询日志中。

3. 设置日志输出方式

MySQL 支持两种方式来记录慢查询日志:文件和表。通常情况下,我们将慢查询日志输出到文件中,但也可以选择将日志记录到 mysql.slow_log 表中,这样我们可以直接通过 SQL 查询进行分析。为了将日志输出到表中,可以使用以下命令:

sql 复制代码
SET GLOBAL log_output = 'TABLE';

此时,慢查询日志将会被写入 mysql.slow_log 表中。

4. 查询慢查询日志

一旦启用了慢查询日志并设置了阈值,你就可以通过查询 mysql.slow_log 表来获取慢查询的详细信息。以下是一个查询示例:

sql 复制代码
SELECT 
    CAST(sql_text AS CHAR) AS query, 
    start_time, 
    query_time, 
    lock_time, 
    rows_examined, 
    rows_sent, 
    db
FROM mysql.slow_log
ORDER BY start_time DESC
LIMIT 20;

此查询会返回最近 20 条慢查询记录,并包括以下字段:

query:执行的 SQL 查询语句。

start_time:查询开始的时间。

query_time:查询的执行时间(秒)。

lock_time:查询的锁定时间。

rows_examined:查询扫描的行数。

rows_sent:查询返回的行数。

db:执行查询时所使用的数据库。

你可以根据实际需求修改查询条件,以便获得更多或更少的慢查询记录。

5. 优化慢查询

一旦获得慢查询日志信息,就可以对这些查询进行优化。优化的方向通常包括:

索引优化:确保查询中涉及到的字段已经创建了适当的索引。

查询重写:通过重写 SQL 查询,减少不必要的全表扫描或复杂的联合查询。

查询分离:对于复杂的查询,可以将其分解成多个较简单的查询。

6. 日常维护与监控

慢查询日志是数据库性能优化的一个重要工具,但它只是其中的一个环节。为了持续监控和优化数据库性能,你可以:

定期分析慢查询日志,并采取相应的优化措施。

配置监控工具(如 Percona Monitoring and Management, Zabbix 等)来实时监控慢查询和数据库性能。

配置报警机制,当查询超时或性能下降时,能够第一时间发现问题。

🔍 慢查询日志表分析SQL集合

1️⃣ 查看最慢的TOP查询

sql 复制代码
-- 找出执行时间最长的20条SQL
SELECT 
    sql_text,
    query_time,
    lock_time,
    rows_examined,
    rows_sent,
    start_time,
    user_host,
    db
FROM mysql.slow_log
ORDER BY query_time DESC
LIMIT 20;

2️⃣ 统计慢查询概况

sql 复制代码
-- 慢查询总体统计
SELECT 
    COUNT(*) as total_slow_queries,
    AVG(query_time) as avg_query_time,
    MAX(query_time) as max_query_time,
    MIN(query_time) as min_query_time,
    SUM(rows_examined) as total_rows_examined,
    AVG(rows_examined) as avg_rows_examined
FROM mysql.slow_log;

3️⃣ 按数据库分组分析

sql 复制代码
-- 各数据库的慢查询统计
SELECT 
    db,
    COUNT(*) as slow_query_count,
    AVG(query_time) as avg_query_time,
    MAX(query_time) as max_query_time,
    SUM(rows_examined) as total_rows_examined
FROM mysql.slow_log
WHERE db IS NOT NULL
GROUP BY db
ORDER BY slow_query_count DESC;

4️⃣ 找出相似SQL(按模式分组)

sql 复制代码
-- 分析相似的慢查询(截取前100个字符)
SELECT 
    LEFT(sql_text, 100) as sql_pattern,
    COUNT(*) as occurrence_count,
    AVG(query_time) as avg_query_time,
    MAX(query_time) as max_query_time,
    AVG(rows_examined) as avg_rows_examined
FROM mysql.slow_log
GROUP BY LEFT(sql_text, 100)
HAVING COUNT(*) > 1
ORDER BY occurrence_count DESC
LIMIT 20;

5️⃣ 按时间段分析

sql 复制代码
-- 按小时统计慢查询分布
SELECT 
    DATE_FORMAT(start_time, '%Y-%m-%d %H:00:00') as hour_time,
    COUNT(*) as slow_query_count,
    AVG(query_time) as avg_query_time,
    MAX(query_time) as max_query_time
FROM mysql.slow_log
WHERE start_time >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY DATE_FORMAT(start_time, '%Y-%m-%d %H:00:00')
ORDER BY hour_time DESC;

6️⃣ 找出扫描行数最多的查询

sql 复制代码
-- 找出全表扫描或扫描行数过多的查询
SELECT 
    sql_text,
    rows_examined,
    rows_sent,
    query_time,
    start_time,
    db,
    ROUND(rows_examined / rows_sent, 2) as scan_efficiency_ratio
FROM mysql.slow_log
WHERE rows_examined > 10000  -- 扫描行数超过1万
ORDER BY rows_examined DESC
LIMIT 20;

7️⃣ 按用户分析

sql 复制代码
-- 各用户的慢查询统计
SELECT 
    user_host,
    COUNT(*) as slow_query_count,
    AVG(query_time) as avg_query_time,
    SUM(rows_examined) as total_rows_examined
FROM mysql.slow_log
GROUP BY user_host
ORDER BY slow_query_count DESC;

8️⃣ 综合分析视图

sql 复制代码
-- 创建一个综合分析结果
SELECT 
    sql_text,
    COUNT(*) as execution_count,
    AVG(query_time) as avg_time,
    MAX(query_time) as max_time,
    MIN(query_time) as min_time,
    AVG(rows_examined) as avg_rows_examined,
    AVG(lock_time) as avg_lock_time,
    MAX(start_time) as last_execution
FROM mysql.slow_log
GROUP BY sql_text
HAVING COUNT(*) > 1  -- 只看执行过多次的
ORDER BY avg_time DESC
LIMIT 30;

总结

慢查询日志功能在 MySQL 中是一个非常实用的工具,帮助我们找到并优化性能瓶颈。通过设置慢查询阈值、日志输出方式以及定期查询日志,可以更有效地监控数据库的执行性能。希望本文能帮助你理解如何在 MySQL 中启用慢查询日志并利用它进行数据库性能优化。如果你有其他问题,欢迎随时提问!

相关推荐
牛奶咖啡132 天前
解决MySQL8.0及其更高版本的两个安全问题——及其配置MySQL实现SSL/TLS加密通信、caching_sha2_password通信
安全·mysql8.0·明文密码登录mysql不安全·忘记mysql用户密码解决方法·mysql主从复制请求安全连接·从库获取主库公钥实现加密通信·mysql配置ssl实现加密
hh真是个慢性子4 天前
mongodb慢查询优化 速度欻欻滴~
数据库·mongodb·性能优化·慢查询
GM_8281 个月前
【Go项目基建】GORM框架实现SQL校验拦截器(完整源码+详解)
sql·golang·拦截器·gorm·慢查询·持久层基建
测试者家园3 个月前
慢查询日志在性能优化中的价值
sql·性能优化·性能测试·慢查询·持续测试·智能化测试
JAVA坚守者4 个月前
MySQL 启动报错 “The server quit without updating PID file“ 的全面解决方案(适用于 5.7/8.0 全版本)
mysql5.7·mysql8.0·mysql 故障排查·数据库启动错误·pid 文件异常·innodb 修复·selinux 问题
李歘歘9 个月前
MySQL数据库——常见慢查询优化方式
数据库·sql·mysql·索引·数据库优化·慢查询
石硕页10 个月前
docker 安装 mysql8.0容器外无法连接
docker·容器·mysql8.0
三两肉1 年前
总结:SQL查询变慢,常见原因分析!
数据库·sql·oracle·sql优化·慢查询
188_djh1 年前
# CentOS7 设置mysql的 root 用户密码时,报错 ERROR 1819(HY000)...ERROR1193... 解决方法。
linux·mysql·centos·centos7·mysql8.0·error1819·error1193