如何解读Ubuntu PHP慢查询日志
慢查询日志是定位PHP应用性能瓶颈的关键工具,它能记录执行时间超过阈值的SQL查询,帮助开发者针对性优化。以下是解读慢查询日志的完整流程:
在解读日志前,需确保PHP(或PHP-FPM)和数据库(如MySQL)的慢查询日志功能已正确开启。
php.ini文件(路径通常为/etc/php/{version}/apache2/php.ini或/etc/php/{version}/fpm/php.ini),设置以下参数:slowlog = /var/log/php-slow.log # 慢日志文件路径(需确保目录可写)
slowlog_timeout = 2 # 慢查询阈值(单位:秒,超过该时间的请求会被记录)
若使用PHP-FPM,还需在www.conf(路径如/etc/php/{version}/fpm/pool.d/www.conf)中确认:slowlog = /var/log/php-fpm/slow.log
request_slowlog_timeout = 2s
my.cnf(或my.ini),添加:[mysqld]
slow_query_log = 1 # 启用慢查询日志
slow_query_log_file = /var/log/mysql/mysql-slow.log # 日志文件路径
long_query_time = 1 # SQL慢查询阈值(秒)
log_queries_not_using_indexes = 1 # 记录未使用索引的查询(即使执行快)
修改后重启服务使配置生效:sudo systemctl restart mysql php{version}-fpm # 根据实际服务名调整
慢查询日志通常包含请求时间、执行时间、查询语句、调用栈等信息(具体格式取决于PHP版本和配置)。常用查看命令:
tail -f /var/log/php-slow.log # 实时跟踪日志更新(按Ctrl+C退出)
cat /var/log/php-slow.log # 直接输出日志内容(适合小文件)
less /var/log/php-slow.log # 分页查看(按q退出)
手动查看日志效率低,推荐使用工具进行聚合、排序、统计,快速定位问题:
sudo apt-get install percona-toolkit # Ubuntu安装
pt-query-digest /var/log/php-slow.log > analysis_report.txt # 生成报告
报告重点关注Top Queries(总耗时最长、出现频率最高的查询),例如:# Query 1: 10.2s (总耗时), 5次(出现次数)
SELECT * FROM users WHERE status = 'active' ORDER BY created_at DESC;
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log # 按执行时间排序,显示前10条
mysqldumpslow -s c -t 10 /var/log/mysql/mysql-slow.log # 按出现次数排序
输出示例:Count: 5 Time=2.1s (10s) Lock=0.0s (0s) Rows=100.0 (500), root[root]@localhost
SELECT * FROM users WHERE status = 'active'
通过工具分析后,需针对Top Queries进一步排查,核心关注以下几点:
key字段(如key=NULL)或数据库的EXPLAIN命令确认是否使用了索引。若未使用,需添加合适的索引(如WHERE子句、JOIN条件的字段)。type列为ALL(如type: ALL)表示全表扫描,通常因缺少索引导致,需优化查询或添加索引。Lock=...(如Lock=1.2s),说明存在锁竞争,需优化事务逻辑(如减少长事务、调整隔离级别)。根据分析结果,采取针对性优化:
ALTER TABLE users ADD INDEX idx_status (status);),但需避免过度索引(会影响INSERT/UPDATE性能)。SELECT *,只查询需要的字段(如SELECT id, name FROM users);JOIN代替子查询(如SELECT u.name FROM users u JOIN orders o ON u.id = o.user_id);LIMIT限制返回行数(如SELECT * FROM users ORDER BY created_at DESC LIMIT 10)。$data = Redis::get('users_active');)。SELECT * FROM orders WHERE user_id = 1拆分为分批次查询)。innodb_buffer_pool_size、max_connections),提升数据库整体性能。慢查询优化是持续过程,需建立监控-审查-优化的闭环: