温馨提示×

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/延迟/错误率变化,验证优化成效并持续迭代。

0