laravel 7 升级到 laravel 9 后变慢并非框架本身变慢,而是因查询逻辑退化(如 wherehas 未改为 whererelation)、缓存未启用(route:cache/config:cache)、n+1 问题复发、缓存驱动仍用 file 等四类隐患所致。

检查是否还在用 whereHas 做深层关联过滤
这是最典型的性能倒退点。Laravel 7 中你可能习惯写:
->whereHas('credit', fn($q) => $q->active())- 而 Laravel 9.2+ 推荐改用
->whereRelation('credit', 'is_active', true)或->whereRelation('credit', fn($q) => $q->has('signature')) -
whereHas会生成子查询(EXISTS),嵌套时极易触发全表扫描;whereRelation编译为 JOIN 或带条件的 EXISTS,可走索引 - 尤其当关联链是
Project → Quotes → Credit且 Credit 还有has('signature')作用域时,旧写法会让 MySQL 执行计划崩溃
确认路由与配置缓存是否启用
升级后这些 Artisan 命令常被忽略,导致每次请求都重新加载:
-
php artisan route:cache—— 路由注册从动态解析变为静态数组,提速显著(尤其路由数 > 50) -
php artisan config:cache—— 避免重复读取 .env 和 config/ 下十几个文件 -
composer dump-autoload -o—— 生成优化的类映射,减少自动加载开销 - 注意:开发环境禁用这些缓存,仅在部署后执行;修改路由或配置后必须先
clear再cache
排查 N+1 是否在新版本中“卷土重来”
Laravel 9 对 Eloquent 的严格模式更敏感,某些写法在 L7 可能“侥幸跑通”,但在 L9+ 更容易暴露:
- 模板中直接调用
$user->posts->count()或$order->items->sum('price')—— 未预加载就触发循环查询 - 升级后若忘了补
with(['posts', 'items']),50 条数据可能瞬间变成 100+ 查询 - 建议开启
DB::connection()->enableQueryLog()(开发环境)或使用 Laravel Debugbar 查看真实 SQL 数量
验证缓存驱动是否仍用 file 或 array
Laravel 9 默认仍配 file 缓存,但生产环境必须切换:
- 检查
.env:确保CACHE_STORE=redis或memcached,而非file - Redis 不仅加速数据缓存,还能支撑 session、队列、广播等——Laravel 9 对 Redis 的集成更成熟
- 若尚未部署 Redis,至少把
SESSION_DRIVER和CACHE_DRIVER改为database(比 file 快得多)











