慢查询日志是分析PHP性能瓶颈的基础,需先通过配置收集相关数据。
php.ini文件,设置slowlog(日志路径,如/var/log/php-slow.log)和request_slowlog_timeout(慢请求阈值,单位:秒,如2表示超过2秒的请求会被记录);my.cnf文件,设置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(记录未使用索引的查询,即使执行快)。systemctl restart php-fpm)和数据库服务(如systemctl restart mysql)使配置生效。配置生效后,让应用运行一段时间(如24小时),慢查询日志会自动记录符合条件的请求和SQL语句。
手动查看日志效率低,推荐使用工具快速定位问题:
mysqldumpslow(MySQL专用):用于聚合相似查询并排序。常用命令如mysqldumpslow -s at -t 10 /var/log/mysql/mysql-slow.log,其中-s at表示按平均查询时间排序,-t 10表示显示前10条记录,可快速找出执行时间最长的SQL;tail -f:实时查看日志新增内容,适合监控当前慢查询(如tail -f /var/log/php-slow.log)。pt-query-digest(Percona Toolkit):比mysqldumpslow更强大,能生成详细的分析报告(包括查询频率、执行时间分布、锁等待情况等),帮助快速定位高频慢查询;Percona Monitoring and Management (PMM)(开源)、Datadog(商业版),提供图形化界面,支持实时监控慢查询趋势、关联数据库与PHP应用性能。慢查询的根本原因通常分为SQL问题、代码逻辑问题两类,需进一步分析:
EXPLAIN命令(如EXPLAIN SELECT * FROM users WHERE status = 'active'),查看执行计划:
type列为ALL,表示全表扫描,需添加索引(如status字段);Extra列包含Using filesort(文件排序)或Using temporary(临时表),表示SQL效率低,需优化查询逻辑(如避免SELECT *、减少JOIN数量);rows列数值过大,表示扫描行数多,需优化查询条件(如添加索引、缩小查询范围)。for循环中多次执行相同的SQL(如foreach ($users as $user) { $db->query("SELECT * FROM orders WHERE user_id = {$user['id']}") }),应改为批量查询(如$db->query("SELECT * FROM orders WHERE user_id IN (" . implode(',', $userIds) . ")"));Swoole或Doctrine DBAL的连接池功能)。EXPLAIN结果添加索引、重写SQL(如将SELECT *改为SELECT id, name减少数据传输)、拆分复杂查询(如将LEFT JOIN改为多次简单查询);pt-query-digest定期分析慢日志(如每天凌晨),并通过邮件或钉钉发送告警(如慢查询数量超过100条时触发);PMM或Datadog实时监控慢查询趋势,及时发现新的性能问题。