ubuntu

Ubuntu PHP日志中的慢查询优化

小樊
38
2025-10-11 12:01:44
栏目: 编程语言

Ubuntu PHP日志中的慢查询优化指南

一、慢查询日志配置(定位问题源头)

1. 启用MySQL慢查询日志

慢查询日志是识别数据库性能瓶颈的核心工具,需先配置MySQL记录执行时间超过阈值的查询。
编辑MySQL配置文件(路径通常为/etc/mysql/mysql.conf.d/mysqld.cnf),添加或修改以下参数:

[mysqld]
slow_query_log = 1                # 开启慢查询日志
slow_query_log_file = /var/log/mysql/slow.log  # 日志文件路径
long_query_time = 2               # 慢查询阈值(单位:秒,默认10秒,建议根据业务调整)
log_queries_not_using_indexes = 1 # 记录未使用索引的查询(可选,帮助优化索引)

保存后重启MySQL服务使配置生效:

sudo systemctl restart mysql

2. 配置PHP-FPM慢查询日志

PHP-FPM的慢日志可记录执行时间过长的PHP请求(包括数据库查询),帮助定位代码中的性能问题。
编辑PHP-FPM池配置文件(路径如/etc/php/7.4/fpm/pool.d/www.conf,根据PHP版本调整),添加或修改以下参数:

[www]
request_slowlog_timeout = 1s      # 慢请求阈值(单位:秒,建议从1秒开始逐步调整)
slowlog = /var/log/php-fpm/www-slow.log  # 慢日志文件路径

重启PHP-FPM服务生效:

sudo systemctl restart php7.4-fpm

3. 查看慢日志

使用tail命令实时查看慢日志,快速定位慢请求:

# 查看MySQL慢日志
tail -f /var/log/mysql/slow.log

# 查看PHP-FPM慢日志
tail -f /var/log/php-fpm/www-slow.log

二、数据库优化(解决核心瓶颈)

1. 分析慢查询日志

使用mysqldumpslow(MySQL自带工具)或pt-query-digest(Percona Toolkit工具)分析慢日志,找出高频慢查询。
示例(使用mysqldumpslow):

# 按查询时间排序,显示前10条慢查询
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

# 显示慢查询的详细信息(包括执行时间、执行次数、SQL语句)
mysqldumpslow -v -t 5 /var/log/mysql/slow.log

2. 添加合适的索引

索引是提升查询速度的关键,需为经常用于WHERE、JOIN、ORDER BY的字段添加索引。

3. 优化SQL查询

4. 定期维护数据库

三、PHP代码优化(减少不必要的开销)

1. 复用数据库连接

避免在每次请求中创建新的数据库连接,使用连接池(如PHP-FPM的pm配置)或持久连接(PDO的PDO::ATTR_PERSISTENT属性)。
示例(PDO持久连接):

$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password', [
    PDO::ATTR_PERSISTENT => true // 开启持久连接
]);

2. 使用预处理语句

预处理语句可防止SQL注入,并提高查询效率(避免SQL编译)。
示例(PDO预处理):

$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $userEmail]);
$results = $stmt->fetchAll();

3. 减少循环中的数据库查询

避免在循环中执行单条SQL,改用批量操作或JOIN查询。
示例(优化前:循环中查询):

foreach ($userIds as $userId) {
    $stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
    $stmt->execute(['id' => $userId]);
    $name = $stmt->fetchColumn();
}

优化后(批量查询):

$placeholders = implode(',', array_fill(0, count($userIds), '?'));
$stmt = $pdo->prepare("SELECT id, name FROM users WHERE id IN ($placeholders)");
$stmt->execute($userIds);
$users = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // 返回[id => name]数组

4. 使用缓存技术

5. 优化循环和递归

四、PHP-FPM配置优化(提升并发处理能力)

1. 调整进程管理参数

编辑PHP-FPM池配置文件(如/etc/php/7.4/fpm/pool.d/www.conf),优化以下参数:

[www]
pm = dynamic                   # 进程管理模式(动态调整进程数)
pm.max_children = 50             # 最大子进程数(根据服务器内存调整,每个进程约消耗10-20MB内存)
pm.start_servers = 5             # 启动时的子进程数
pm.min_spare_servers = 5         # 最小空闲子进程数(避免频繁创建进程)
pm.max_spare_servers = 35        # 最大空闲子进程数(避免占用过多内存)
pm.max_requests = 1000           # 每个子进程处理的最大请求数(避免内存泄漏)

重启PHP-FPM生效:

sudo systemctl restart php7.4-fpm

2. 调整请求超时时间

根据业务需求调整request_terminate_timeout参数,避免长时间运行的脚本占用资源:

request_terminate_timeout = 30s  # 超时时间(秒,建议设置为30-60秒)

五、系统级优化(提升整体性能)

1. 升级硬件

2. 监控与告警

六、常用工具推荐

0
看了该问题的人还看了