慢查询日志:定位性能瓶颈

一、什么是慢查询日志 1.1 定义 记录执行时间超过阈值的SQL语句。 1.2 作用 定位慢SQL 分析性能瓶颈 优化数据库性能 二、配置慢查询日志 2.1 查看当前配置 -- 是否启用 SHOW VARIABLES LIKE 'slow_query_log'; -- OFF(未启用) -- 慢查询阈值 SHOW VARIABLES LIKE 'long_query_time'; -- 10(默认10秒) -- 日志文件路径 SHOW VARIABLES LIKE 'slow_query_log_file'; 2.2 启用慢查询日志 -- 方式1:临时启用(重启失效) SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2; -- 2秒 -- 方式2:配置文件永久启用 -- my.cnf [mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 log_queries_not_using_indexes = 1 -- 记录未使用索引的查询 2.3 重启生效 systemctl restart mysqld 三、慢查询日志格式 3.1 日志示例 # Time: 2024-11-21T22:30:00.123456Z # User@Host: root[root] @ localhost [] # Query_time: 5.123456 Lock_time: 0.000123 Rows_sent: 100 Rows_examined: 1000000 SET timestamp=1700601000; SELECT * FROM orders WHERE status = 'pending' ORDER BY created_at; 3.2 关键字段 Query_time:查询执行时间(秒) Lock_time:锁等待时间 Rows_sent:返回行数 Rows_examined:扫描行数 四、分析慢查询日志 4.1 查看慢查询日志 tail -f /var/log/mysql/slow.log 4.2 mysqldumpslow工具 # 查看出现次数最多的10条慢SQL mysqldumpslow -s c -t 10 /var/log/mysql/slow.log # 查看执行时间最长的10条慢SQL mysqldumpslow -s t -t 10 /var/log/mysql/slow.log # 查看返回记录最多的10条慢SQL mysqldumpslow -s r -t 10 /var/log/mysql/slow.log # 查看锁等待时间最长的10条慢SQL mysqldumpslow -s l -t 10 /var/log/mysql/slow.log 参数说明: ...

2025-11-20 · maneng

MySQL查询优化:从执行计划到性能调优

引言 “过早优化是万恶之源。但当性能问题真正出现时,优化就是救命稻草。” —— Donald Knuth 在前三篇文章中,我们学习了索引、事务、锁的原理。但光有理论还不够,如何定位和优化慢查询? 想象这样的场景: 凌晨3点,你被一通电话吵醒: "数据库快挂了,所有查询都超时!" 你打开监控,发现: - CPU 100% - 慢查询日志爆满 - 某个SQL执行了10秒还没返回 如何快速定位问题?如何优化这个慢查询? 这就是查询优化的核心价值:让慢查询变快,让系统起死回生。 今天,我们从第一性原理出发,深度剖析MySQL的查询优化: SQL执行流程: 客户端 → 连接器 → 解析器 → 优化器 → 执行器 → 存储引擎 ↓ ↓ ↓ ↓ ↓ 权限检查 语法解析 生成计划 执行查询 返回数据 性能优化: 慢查询 → EXPLAIN → 找到瓶颈 → 优化索引 → 改写SQL → 性能飞跃 10秒 分析 全表扫描 建索引 覆盖索引 10ms 我们还将通过10个真实案例,将慢查询从10秒优化到10ms,性能提升1000倍。 一、SQL执行流程:从SQL到结果集 理解查询优化,首先要理解SQL是如何执行的。 1.1 MySQL的架构:两层结构 ┌─────────────────────────────────────────────────────────────┐ │ MySQL Server层 │ ├─────────────────────────────────────────────────────────────┤ │ 连接器 解析器 优化器 执行器 │ │ ↓ ↓ ↓ ↓ │ │ 权限验证 语法解析 生成计划 执行查询 │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 存储引擎层 │ ├─────────────────────────────────────────────────────────────┤ │ InnoDB MyISAM Memory Archive │ │ ↓ ↓ ↓ ↓ │ │ 事务支持 不支持 内存存储 压缩存储 │ └─────────────────────────────────────────────────────────────┘ Server层与存储引擎的职责分工: ...

2025-11-03 · maneng

MySQL查询优化:从执行计划到性能调优

引言 “过早优化是万恶之源。但当性能问题真正出现时,优化就是救命稻草。” —— Donald Knuth 在前三篇文章中,我们学习了索引、事务、锁的原理。但光有理论还不够,如何定位和优化慢查询? 想象这样的场景: 凌晨3点,你被一通电话吵醒: "数据库快挂了,所有查询都超时!" 你打开监控,发现: - CPU 100% - 慢查询日志爆满 - 某个SQL执行了10秒还没返回 如何快速定位问题?如何优化这个慢查询? 这就是查询优化的核心价值:让慢查询变快,让系统起死回生。 今天,我们从第一性原理出发,深度剖析MySQL的查询优化: SQL执行流程: 客户端 → 连接器 → 解析器 → 优化器 → 执行器 → 存储引擎 ↓ ↓ ↓ ↓ ↓ 权限检查 语法解析 生成计划 执行查询 返回数据 性能优化: 慢查询 → EXPLAIN → 找到瓶颈 → 优化索引 → 改写SQL → 性能飞跃 10秒 分析 全表扫描 建索引 覆盖索引 10ms 我们还将通过10个真实案例,将慢查询从10秒优化到10ms,性能提升1000倍。 一、SQL执行流程:从SQL到结果集 理解查询优化,首先要理解SQL是如何执行的。 1.1 MySQL的架构:两层结构 ┌─────────────────────────────────────────────────────────────┐ │ MySQL Server层 │ ├─────────────────────────────────────────────────────────────┤ │ 连接器 解析器 优化器 执行器 │ │ ↓ ↓ ↓ ↓ │ │ 权限验证 语法解析 生成计划 执行查询 │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 存储引擎层 │ ├─────────────────────────────────────────────────────────────┤ │ InnoDB MyISAM Memory Archive │ │ ↓ ↓ ↓ ↓ │ │ 事务支持 不支持 内存存储 压缩存储 │ └─────────────────────────────────────────────────────────────┘ Server层与存储引擎的职责分工: ...

2025-11-03 · maneng

慢查询优化:发现与解决性能瓶颈

慢查询配置 # 慢查询阈值(微秒),默认10000(10ms) CONFIG SET slowlog-log-slower-than 10000 # 慢查询日志最大长度 CONFIG SET slowlog-max-len 128 # 持久化配置 # redis.conf slowlog-log-slower-than 10000 slowlog-max-len 128 查看慢查询 # 获取所有慢查询 SLOWLOG GET [count] # 获取慢查询数量 SLOWLOG LEN # 清空慢查询 SLOWLOG RESET 输出示例: redis> SLOWLOG GET 5 1) 1) (integer) 6 # 日志ID 2) (integer) 1609459200 # 时间戳 3) (integer) 12000 # 执行时间(微秒) 4) 1) "KEYS" # 命令 2) "*" 5) "127.0.0.1:50796" # 客户端 6) "" # 客户端名称 Java监控慢查询 @Component public class SlowQueryMonitor { @Autowired private RedisTemplate<String, String> redis; @Scheduled(fixedRate = 60000) // 每分钟 public void checkSlowQueries() { List<Object> slowlogs = redis.execute((RedisCallback<List<Object>>) connection -> connection.slowlogGet(100) ); if (slowlogs != null && !slowlogs.isEmpty()) { for (Object log : slowlogs) { // 解析慢查询日志 Map<String, Object> slowlog = parseSlowlog(log); long duration = (long) slowlog.get("duration"); String command = (String) slowlog.get("command"); // 告警阈值:超过50ms if (duration > 50000) { log.warn("慢查询告警: command={}, duration={}ms", command, duration / 1000); // 发送告警 sendAlert(command, duration); } } // 清空已分析的慢查询 redis.execute((RedisCallback<Void>) connection -> { connection.slowlogReset(); return null; }); } } private Map<String, Object> parseSlowlog(Object log) { // 解析慢查询日志格式 return new HashMap<>(); } private void sendAlert(String command, long duration) { // 发送告警(邮件/短信/钉钉) } } 常见慢命令 1. KEYS命令 # ❌ 极慢:遍历所有key,O(N) KEYS * KEYS user:* # ✅ 好:使用SCAN,渐进式遍历 SCAN 0 MATCH user:* COUNT 100 Java替代方案: ...

2025-01-21 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...