性能优化
Laravel 数据库性能优化:写 Eloquent 查询…
在 Laravel 应用中编写 Eloquent 查询、创建迁移、配置缓存、调试慢查询或优化数据库性能时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
Laravel 数据库性能优化:写 El通用
解决思路
- 用预加载(eager loading)消除 N+1 查询。
- 在开发环境阻止懒加载:在 AppServiceProvider 的 boot 中调用 Model::preventLazyLoading(!app()->isProduction())。
- 在模型上配置自动预加载(auto eager loading)。
- 只选择需要的列,避免 SELECT *。
- 为所有外键列建立索引。
- 为多列查询创建复合索引。
- 对读密集查询使用覆盖索引(covering index)。
- 为搜索功能使用全文索引(full-text index)。
- 在性能关键路径上使用查询构建器(query builder)替代 Eloquent。
- 用 withCount 统计关联数量,而不是加载关联后再计数。
- 用子查询 select 避免额外查询。
- 用 whereIn 子查询优化 whereHas。
- 用 Cache::remember 缓存昂贵查询,例如 Cache::remember('posts:popular', 3600, fn () => Post::query()->withCount('comments')->orderByDesc('comments_count')->take(10)->get())。
- 在模型变更时使缓存失效。
- 用缓存标签(cache tags)做分组失效。
- 为缓存数据设置合适的 TTL。
- 大数据集使用游标分页(cursor pagination),例如 Post::query()->where('published_at', '<=', now())->orderByDesc('published_at')->cursorPaginate(15)。
- 用 chunkById 处理大数据集,例如 User::query()->where('last_login_at', '<', now()->subYear())->chunkById(1000, function ($users) { foreach ($users as $user) { $user->update(['status' => 'inactive']); } })。
- 用 lazy cursors 做内存高效的迭代。
- 绝不在大表上使用无界查询。
- 保持事务短小聚焦,例如 DB::transaction(function () { $order = Order::create([...]); $order->items()->createMany($this->cartItems()); $order->user->decrement('credits', $order->total); })。
- 实现死锁重试逻辑。
- 对关键更新使用悲观锁(pessimistic locking)。
- 编写零停机迁移(zero-downtime migrations)。
- 在生产环境并发创建索引(concurrent indexes)。
- 安全地添加列,避免锁表。
- 用 EXPLAIN ANALYZE 理解查询计划。
- 用 Laravel Debugbar 定位查询瓶颈。
- 启用并监控慢查询日志。
- 遵循表命名约定:复数 snake_case,中间表按字母顺序。
- 遵循列命名约定:外键、布尔值、时间戳、多态。
- 遵循关系方法命名约定:单数/复数匹配。
- 遵循迁移与索引命名约定。
适用边界 · 注意事项
- 非 Laravel 项目或非 PHP 8.3+/Laravel 13.x 环境不适用。
- 未使用 Redis 或缓存后端时,缓存相关规则无法直接落地。
- 小型数据集或一次性脚本中,过度索引与缓存可能带来不必要的复杂度。