Ubuntu PHP日志中的慢查询怎么办
小樊
31
2025-12-19 20:55:02
Ubuntu PHP慢查询的定位与优化全流程
一 明确慢查询来源与差异
- PHP层面常说的“慢查询”通常有两层含义:
- PHP-FPM慢请求日志:记录单个请求在PHP层面执行超过阈值的调用栈(如某个函数、include、数据库调用等),用于定位PHP代码瓶颈。
- 数据库慢查询日志:记录SQL执行超过阈值的语句,用于定位SQL与索引问题。
- 二者相辅相成:先通过PHP-FPM慢日志找到“慢的入口”,再用数据库慢日志与EXPLAIN定位具体SQL与索引。
二 启用并解读PHP-FPM慢请求日志
- 编辑对应PHP版本的FPM池配置(路径因版本不同,如**/etc/php/8.1/fpm/pool.d/www.conf**):
- 开启慢日志与阈值:
- slowlog = /var/log/php-fpm/www-slow.log
- request_slowlog_timeout = 1s
- 说明:当request_slowlog_timeout设为非0时,slowlog必须配置;阈值可按业务调整为0.5s/1s/2s。
- 创建日志目录并授权(以www-data为例):
- sudo mkdir -p /var/log/php-fpm
- sudo chown www-data:www-data /var/log/php-fpm
- 重启FPM生效:
- sudo systemctl restart php8.1-fpm
- 典型慢日志解读要点(示例):
- 首行包含时间、进程池与脚本路径:script_filename = /var/www/html/index.php
- 后续多行为调用栈,定位到具体函数/文件/行号,例如:session_start() /var/www/html/app/models/User.php:11
- 据此优先优化这些热点函数或引入缓存/延迟加载。
三 启用并分析数据库慢查询日志
- MySQL慢查询日志(示例为MySQL 5.7+/8.0):
- 临时开启与阈值设置(会话或全局):
- SET GLOBAL slow_query_log = ON;
- SET GLOBAL long_query_time = 1;(单位秒,可按需调整)
- 永久配置(编辑**/etc/mysql/mysql.conf.d/mysqld.cnf**或/etc/my.cnf):
- [mysqld]
- slow_query_log = 1
- slow_query_log_file = /var/log/mysql/slow.log
- long_query_time = 1
- log_queries_not_using_indexes = 1(可选,记录未使用索引的查询)
- 重启数据库:sudo systemctl restart mysql
- 分析工具与用法:
- 自带工具:
- mysqldumpslow -s at -t 10 /var/log/mysql/slow.log(按平均时间取前10条)
- 高级工具:
- 安装Percona Toolkit:sudo apt-get install percona-toolkit
- pt-query-digest /var/log/mysql/slow.log > slow_report.txt(生成统计与样本)
- 用EXPLAIN验证问题SQL:
- EXPLAIN SELECT …; 关注type是否为ALL(全表扫描)、key是否为NULL(未用索引)、rows是否过大,据此添加/改写索引与SQL。
四 常见优化手段与配置建议
- SQL与索引优化:
- 为WHERE、JOIN、ORDER BY、GROUP BY涉及列建立合适索引;避免SELECT *;减少子查询与函数包裹列;分页使用LIMIT;必要时用覆盖索引减少回表。
- PHP-FPM进程与超时:
- 合理设置进程模型与数量(示例为dynamic):
- pm = dynamic
- pm.max_children = 50
- pm.start_servers = 5
- pm.min_spare_servers = 5
- pm.max_spare_servers = 35
- request_terminate_timeout = 30s(与业务超时策略一致)
- 结合监控逐步调优,避免过高并发导致资源争用。
- 缓存与执行计划优化:
- 启用并调优OPcache(生产建议开启):
- [opcache]
- opcache.enable=1
- opcache.memory_consumption=128
- opcache.interned_strings_buffer=8
- opcache.max_accelerated_files=4000
- 引入Redis/Memcached做查询结果/页面片段缓存,降低数据库压力。
- 异步与脱钩:
- 将耗时任务(邮件、导出、图片处理等)放入队列(如RabbitMQ/Redis),由Worker异步处理,缩短HTTP请求耗时。
- 监控与持续改进:
- 使用New Relic/Datadog/Blackfire等APM与性能分析工具,结合FPM状态页与MySQL慢日志,形成闭环优化。
五 快速排查清单
- 确认FPM慢日志已开启且阈值合理(如1s),并能在日志中看到具体函数/文件/行号。
- 打开MySQL慢查询日志,先用pt-query-digest或mysqldumpslow找出Top N慢SQL,再用EXPLAIN检查执行计划与扫描行数。
- 优先处理“高频+高耗时”的SQL:加索引、改写SQL、减少返回列与扫描量。
- 在PHP侧做缓存与N+1查询治理(预加载/批量查询),必要时用消息队列解耦耗时任务。
- 调整FPM进程数与超时,避免雪崩;开启OPcache减少编译开销。
- 建立例行巡检:每周分析慢日志、观察QPS/延迟/错误率变化,验证优化成效并持续迭代。