Laravel 9 数据库查询缓存优化需选 Redis/Memcached 驱动、设计带业务语义的版本化键名、分级设置 TTL、并结合事件主动清理。

优化 Laravel 9 数据库查询缓存性能,核心是让缓存“用得准、存得稳、失效及时”,而不是简单加个 remember() 就完事。重点在于缓存驱动选型、键名设计、生命周期控制和主动清理机制。
选对缓存驱动,别用文件或数据库存高频查询
默认的 file 驱动在并发下性能差、不支持原子操作;database 驱动反而增加数据库负担。生产环境务必切换到 redis 或 memcached:
- 在
.env中设置:CACHE_DRIVER=redis - 确保 Redis 已启用持久化与合理内存策略(如
maxmemory-policy allkeys-lru) - 避免把大对象(如含附件 URL 的完整模型集合)直接缓存,先用
pluck()或map()剥离必要字段
缓存键要带业务语义,支持精准清理
静态键如 'users' 看似简单,但无法区分角色、状态或租户,容易导致脏读或缓存污染:
- 按维度组合键名:例如
"users:active:dept_{$id}:v2",其中v2用于版本升级时批量失效 - 关联数据缓存需包含外键值:如
"posts:by_user_{$userId}:recent",方便用户更新后只清该用户的帖子缓存 - 用
Cache::tags()(仅 Redis/Memcached 支持)做逻辑分组:Cache::tags('posts')->remember(...),后续可一键清除所有文章相关缓存
设置合理 TTL,避免缓存雪崩与长尾延迟
TTL 不是越长越好。过长会导致数据陈旧,过短则频繁回源、失去缓存意义:
- 读多写少的数据(如站点配置、分类列表):30 分钟到 24 小时
- 用户个人数据(如权限、偏好):10–60 分钟,且在登录/修改后立即
forget() - 热门榜单类(如“今日 Top10”):5–15 分钟,配合定时任务预热新缓存
- 避免全站统一设 3600 秒——不同数据变更频率差异大,应分级设定
主动管理缓存,不是等它自动过期
依赖 TTL 被动失效,在高一致性场景下风险高。关键数据必须配合业务事件主动清理:
- 在模型的
updating/updated事件中触发清除:Cache::forget("user_{$this->id}"); - 使用观察者(Observer)监听
Post更新,同时清除"posts:recent"和对应分类的缓存键 - 对批量操作(如后台导入、状态同步),用
Cache::tags('posts')->flush()或通配符删除(Redis 可用SCAN+DEL脚本)



















