
php 本身不生成数据库执行计划,执行计划由数据库服务器(如 mysql、postgresql)生成;PHP 的作用是发送 SQL 查询并获取结果。要分析执行计划,关键在于在数据库层面捕获和解读 EXPLAIN 输出,再结合 PHP 应用的查询构造逻辑进行优化。
在 PHP 中触发并查看 MySQL 执行计划
不要在 PHP 中直接“执行 EXPLAIN”后手动解析,而应将 EXPLAIN 作为调试手段嵌入开发流程:
- 对慢查询或关键业务 SQL,在调用前加
EXPLAIN前缀,例如:
`$sql = “EXPLAIN SELECT * FROM users WHERE status = ? AND created_at > ?”;` - 使用 pdo 或 mysqli 执行该语句,获取结果集(通常是二维数组),重点关注
type、key、rows、Extra字段 - 避免在生产环境频繁执行
EXPLAIN,建议仅在调试阶段开启,或通过日志开关控制
识别常见低效执行模式(对应 EXPLAIN 关键字段)
以下现象往往意味着性能隐患,需结合 PHP 查询构造方式排查:
- type = ALL:全表扫描,通常因缺失 WHERE 条件索引或使用了无法走索引的表达式(如
WHERE YEAR(created_at) = 2024)——PHP 中应改用范围查询:"created_at >= '2024-01-01' AND created_at - key 为 NULL:未命中任何索引,检查 PHP 拼接的条件字段是否与索引列一致(大小写、隐式类型转换,如用字符串比较整型主键)
- Extra 包含 using filesort / Using temporary:ORDER BY 或 GROUP BY 未利用索引排序,PHP 中应确保排序字段已包含在联合索引最左前缀中,或避免在查询中计算字段排序(如
ORDER BY CONCAT(first_name, last_name))
结合 PHP ORM 或查询构建器做计划验证
使用 laravel Eloquent、thinkphp QueryBuilder 等时,SQL 由框架动态生成,容易忽略执行计划:
立即学习“PHP免费学习笔记(深入)”;
- 开启查询日志(如 Laravel 的
DB::enableQueryLog()),捕获实际执行的 SQL,再手动在数据库中运行EXPLAIN - 警惕 N+1 查询:PHP 循环中多次调用
->relation(),虽单条简单,但整体放大 I/O;应改用with('relation')预加载,并确认预加载 SQL 的执行计划是否高效 - 对复杂查询(如多表 join + 子查询),先用原生 SQL +
EXPLAIN format=json获取详细分析,再反推 PHP 构建逻辑是否可简化或拆分
自动化辅助:轻量级执行计划快照工具
可在 PHP 开发/测试环境中快速比对计划变化: