应使用cache::remember()或eloquent的remember()方法缓存查询结果,配合redis驱动、合理键名设计、ttl设置及变更时主动清除,避免n+1与重复查询。

如果您在Laravel应用中频繁执行相同数据库查询,导致数据库负载升高、响应延迟增加,则可能是由于未合理启用或配置查询缓存。以下是针对Laravel框架缓存查询设置与数据库减负的具体操作方法:
一、使用remember()方法缓存Eloquent查询结果
该方法将查询结果序列化后存入配置的缓存驱动(如Redis、File、Memcached),后续相同查询在缓存有效期内直接返回缓存值,跳过数据库访问。
1、在控制器或服务类中调用remember()并指定缓存时长(单位:秒):
2、User::where('status', 1)->remember(3600)->get();
3、若需动态生成缓存键以区分不同参数条件,可传入自定义键名:
4、User::where('department_id', $deptId)->remember(1800, 'users_dept_'.$deptId)->get();
5、对复杂查询链式调用同样适用,remember()必须置于get()或first()等终值方法之前:
6、Post::with('author')->where('published', true)->remember(7200)->orderBy('created_at', 'desc')->paginate(15);
二、使用Cache::remember()封装原生或复杂查询逻辑
当查询涉及多表联合、聚合函数或DB::select等非Eloquent操作时,可借助Cache门面手动管理缓存生命周期,获得更高控制粒度。
1、引入Cache门面并在闭包中执行实际查询:
2、use Illuminate\Support\Facades\Cache;
3、$topPosts = Cache::remember('popular_posts_7d', 604800, function () { return DB::table('posts')->select('id', 'title', 'view_count')->where('created_at', '>=', now()->subWeek())->orderByDesc('view_count')->limit(10)->get(); });
4、缓存键支持嵌套变量和业务标识,便于清理特定范围缓存:
5、Cache::remember('stats:users:active:'.$year, 3600, fn() => User::where('last_login_at', '>=', "$year-01-01")->count());
三、为高频权限/角色查询添加内存级缓存
避免在用户模型中每次调用hasRole()、isCustomer()等方法都触发独立数据库查询,改用一次加载+内存复用策略,彻底消除N+1权限查询问题。
1、重写User模型中的roles关系,添加缓存属性:
2、protected $cachedRoles = null;
3、在hasRole()方法中优先读取缓存,未命中再查库并写入:
4、public function hasRole($role) { if ($this->cachedRoles === null) { $this->cachedRoles = $this->roles()->pluck('name')->toArray(); } return in_array($role, $this->cachedRoles); }
5、确保首次访问后该用户实例生命周期内无需重复查询角色表:
6、auth()->user()->isCustomer(); // 复用已加载的角色数组,零数据库查询
四、配置全局查询缓存开关与驱动优化
通过修改cache.php与database.php配置文件,统一约束缓存行为,防止开发人员误用默认驱动造成性能回退。
1、确认config/cache.php中default值指向高性能驱动(如redis):
2、'default' => env('CACHE_DRIVER', 'redis'),
3、在config/database.php中为查询构造器启用默认缓存前缀与TTL策略:
4、'cache' => [ 'enabled' => true, 'prefix' => 'dbquery:', 'ttl' => 3600, ],
5、强制所有DB查询遵守该配置,无需逐处添加remember():
6、DB::table('settings')->where('key', 'site_name')->value('value'); // 自动缓存,键名为 dbquery:settings:site_name
五、结合模型事件自动刷新关联缓存
当被缓存的数据源发生变更(如用户更新头像、文章状态切换),需同步失效对应缓存项,保证数据一致性,避免脏读。
1、在App\Models\Post模型中监听saved与deleted事件:
2、protected $dispatchesEvents = [ 'saved' => \App\Events\PostUpdated::class, 'deleted' => \App\Events\PostDeleted::class ];
3、在对应事件监听器中清除相关缓存键:
4、Cache::forget('post_detail_'.$post->id); Cache::forget('latest_posts'); Cache::tags(['posts'])->flush();
5、对带标签的缓存驱动(如Redis),使用Cache::tags()实现批量失效,提升维护效率:
6、Cache::tags(['users', 'profiles'])->put('user_'.$id.'_profile', $data, 3600);











