在phpEnv中快速定位MySQL高CPU的罪魁SQL:先通过面板启用慢查询日志(long_query_time=1),再用SHOW FULL PROCESSLIST筛选Time>5s且State异常的查询;对可疑SQL执行EXPLAIN,type=ALL或rows远大于返回行数即需优化,优先建符合最左前缀的联合索引,并检查OPcache配置是否合理。

phpEnv里怎么快速定位MySQL高CPU的罪魁SQL
phpEnv本身不干预MySQL运行,但它的面板集成了慢日志开关和进程列表入口——别去翻配置文件,直接点「数据库」→「性能优化」启用慢查询日志,long_query_time设为1,日志路径默认是/www/server/mysql/log/slow-query.log。同时打开终端执行:mysql -uroot -p -e "SHOW FULL PROCESSLIST;" | grep -E "(Query|State)",重点关注Time列超过5秒、State是Sorting result或Copying to tmp table的行。
注意:Sleep状态的连接别乱KILL——那是PHP-FPM维持的空闲连接池,杀完立刻重建,还可能触发应用重连风暴。
EXPLAIN里看到type=ALL就该建索引了
拿到可疑SQL后,用EXPLAIN FORMAT=TRADITIONAL SELECT ...看执行计划。只要type是ALL,说明在全表扫描;如果rows远大于实际返回行数(比如查10条却扫50万行),CPU飙高就是必然结果。
- WHERE条件含多个字段?优先建联合索引,顺序按“最左前缀”原则,例如
WHERE status = 1 AND created_at > '2024-01-01',建INDEX idx_status_created (status, created_at)比单列索引有效得多 - 避免在低区分度字段(如
gender只有'M'/'F')上单独建索引;若必须参与过滤,把它放联合索引后部 -
ORDER BY或GROUP BY字段没走索引?Extra里会显示Using filesort或Using temporary,这类语句CPU消耗极重
phpEnv环境下OPcache没调对,等于白开
PHP层解析编译开销会在高并发下被急剧放大,而phpEnv默认的OPcache参数对中大型项目基本无效。
立即学习“PHP免费学习笔记(深入)”;
-
opcache.memory_consumption至少设为256(单位MB),小项目可192,但别低于128 -
opcache.max_accelerated_files必须大于你项目真实PHP文件数,用find /path/to/www -name "*.php" | wc -l算出来,建议直接设20000 -
opcache.revalidate_freq生产环境设60足够,设0会导致大量stat()系统调用,反而拖慢CPU - 确认生效:执行
php -i | grep opcache,确保opcache.enable => On且opcache.huge_code_pages => Off(开启需内核支持,否则降速)
索引不是越多越好,删掉这些才真省CPU
冗余或低效索引会拖慢写入、占用内存、干扰优化器选错执行计划——它们在phpEnv的「数据库」→「管理」里看不到,得手动查。
- 查冗余索引:
SELECT * FROM sys.schema_redundant_indexes;(需启用sys库) - 查未使用索引:
SELECT * FROM sys.schema_unused_indexes WHERE object_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); - 特别警惕
WHERE a = ? ORDER BY b这种查询,如果只建了(a)或(b)单列索引,大概率不如建(a, b)覆盖索引 - 删除前先用
EXPLAIN对比执行计划,防止误删导致某条高频SQL退化成全表扫描
真正卡住CPU的往往不是某条SQL多复杂,而是它每天被调用几千次却始终没走索引——这种问题在phpEnv里改个索引、调两行OPcache参数就能立竿见影,但容易被当成“服务器老化”忽略。



















