核心思路是结合框架日志、数据库原生慢日志与实时会话监控三者互补:先确认MySQL慢查询日志是否开启(slow_query_log=ON)、阈值合理(long_query_time=0.5~1秒),再利用Hyperf SQL耗时埋点定位接口级慢SQL,最后通过SHOW PROCESSLIST实时抓取正在执行的高耗时会话。

Hyperf 项目中定位 MySQL 慢查询,核心思路是:**结合框架日志 + 数据库原生慢日志 + 实时会话监控**,三者互补,避免只依赖单一来源。Hyperf 本身不直接生成慢 SQL 报告,但提供了完善的 SQL 执行耗时埋点能力,配合 MySQL 配置即可快速闭环。
开启并确认 MySQL 慢查询日志
这是最权威的“事后证据”,必须优先检查:
- 登录 MySQL 执行:
SHOW VARIABLES LIKE 'slow_query_log';确认是否为ON - 检查阈值:
SHOW VARIABLES LIKE 'long_query_time';生产建议设为0.5或1(单位:秒) - 确认日志路径:
SHOW VARIABLES LIKE 'slow_query_log_file';,常见如/var/lib/mysql/xxx-slow.log - 若未开启,可临时启用:
SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 1;(重启失效) - 推荐永久配置(
/etc/my.cnf或/etc/mysql/my.cnf):slow_query_log = 1<br>long_query_time = 1<br>log_queries_not_using_indexes = 1
利用 Hyperf 自带的 SQL 日志追踪
Hyperf 的 Db 组件默认开启 SQL 执行日志(需配置),能直接在应用层看到哪条 SQL 耗时高:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 确保
config/autoload/db.php中'options' => [PDO::ATTR_EMULATE_PREPARES => true]及日志级别足够(如debug) - 在
config/autoload/logger.php中确认db通道已启用且输出到文件或控制台 - 观察日志中类似内容:
[DEBUG] SQL: SELECT * FROM users WHERE id = ? | Time: 1248.33ms - 注意:该耗时包含网络往返、PHP 处理、结果集解析等,比 MySQL 引擎内实际执行时间略长,但对定位接口级瓶颈非常直观
实时抓取正在执行的慢会话
当问题正在发生(如 CPU 突增、请求堆积),用此法最快锁定“活”的慢 SQL:
- 执行:
SHOW FULL PROCESSLIST;查看所有连接状态 - 重点关注
Time > 1且State为Sending data、Copying to tmp table、Sorting result的记录 - 更精准筛选:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM information_schema.PROCESSLIST WHERE TIME > 1 AND INFO IS NOT NULL ORDER BY TIME DESC LIMIT 10; - Hyperf 应用里常出现
sleep连接(空闲连接池)和真实执行中的长耗时语句,注意区分
进阶:用 mysqldumpslow 或 pt-query-digest 分析日志
当日志积累后,靠人工翻查效率低,用工具提炼重点:
-
mysqldumpslow -s t -t 10 /var/lib/mysql/*.slow:提取执行时间最长的前 10 条 -
mysqldumpslow -s c -t 10 /var/lib/mysql/*.slow:提取出现频次最高的前 10 条(高频低耗时也可能压垮数据库) - 如需深度分析(如指纹归类、平均延迟、锁等待),推荐
pt-query-digest:pt-query-digest /var/lib/mysql/*.slow > report.txt - 特别注意报告中
Rows_examined和Rows_sent比值——若扫描百万行只返回几条,大概率缺索引或条件失效










