n+1问题需用debugbar定位并用with预加载修复;mix慢应禁用version/extract、调优sourcemap和babel;生产session须用redis并区分prefix;artisan慢要裁剪服务提供者、清config缓存。

数据库查询 N+1 问题怎么快速定位和修复
绝大多数 Laravel 应用的性能瓶颈不在 PHP 本身,而在没控制好的数据库查询。N+1 最典型的表现是:列表页加载慢、DB::listen() 显示几十上百条相似 select * from users where id = ? 查询。
用 php artisan tinker 模拟请求,配合 DB::enableQueryLog() 和 DB::getQueryLog() 看实际发了哪些 SQL;更推荐直接在开发环境开启 barryvdh/laravel-debugbar,它会标红高亮 N+1 查询。
- 关系预加载必须显式写
->with('posts', 'comments.user'),不能依赖懒加载 -
withCount()替代count()循环调用,避免额外聚合查询 - 关联字段只查需要的列,比如
->with(['posts' => function ($q) { $q->select('id', 'title', 'user_id'); }]) - 避免在 Blade 中写
{{ $user->posts->count() }}—— 这会触发懒加载,且每次渲染都查一次
Laravel Mix 构建慢、热更新卡顿怎么办
不是 Webpack 本身慢,而是默认配置没关掉开发期无用的步骤。常见现象:改一行 CSS,npm run watch 卡住 5 秒以上;保存后浏览器没反应,或 HMR 失效。
关键在 webpack.mix.js 的配置取舍:
- 开发期禁用
.version()和.extract(),它们会强制重算 chunk hash - 关闭 SourceMap 类型:把
devtool: 'source-map'改成'eval-source-map'或直接删掉(Laravel Mix 默认已设为轻量级) - 限制 Babel 编译范围:
.babelConfig({ targets: { node: 'current' } })避免全量 polyfill - 图片/字体等静态资源不走
.copy(),改用.copyDirectory()并加.watchFiles()排除 node_modules
Session 和缓存驱动选什么才不拖慢请求
本地开发用 file 驱动没问题,但上线后若还用 file 或 database 存 session,每个请求都要磁盘 I/O 或 DB 连接,QPS 直接腰斩。
生产必须切到内存型驱动,但要注意细节差异:
-
redis是首选:session 和 cache 共享同一 Redis 实例时,注意设置不同prefix,否则cache:clear可能清掉 session -
memcached也行,但不支持原子性 TTL 更新,session 过期逻辑略弱于 Redis - 别用
array驱动上线 —— 它只存在单次请求内存里,根本不算 session - 检查
config/cache.php中default和stores.redis.connection是否指向正确 Redis DB(比如 DB 0 存缓存,DB 1 存 session)
Artisan 命令执行慢,队列任务卡住不动
不是命令本身慢,而是它隐式触发了完整 Laravel 启动流程,又没跳过不必要的服务提供者。典型症状:php artisan list 要 1.5 秒、queue:work 启动延迟高、任务日志迟迟不输出。
优化点集中在启动阶段裁剪:
- 给自定义 Artisan 命令加
protected $signature = 'xxx {--no-interaction}';,并确保不依赖ConsoleServiceProvider之外的 UI 组件 - 队列 worker 必须用
--daemon模式(Laravel 9+ 默认启用),否则每次任务都重新 boot 应用 - 检查
app/Providers/AppServiceProvider.php中是否在boot()里做了阻塞操作,比如同步调用外部 API 或大文件读取 - 用
php artisan config:clear和php artisan view:clear清理缓存,避免配置/视图编译器拖慢首次加载
最常被忽略的是:config 缓存没清,导致所有环境变量还是从 .env 动态读取 —— 这个开销比你想象中大得多。











