codeigniter数据库查询缓存需手动开启:先配置cachedir路径并确保可写,再在select前调用$this->db->cache_on(),查完建议cache_off();仅select生效,增删改后须手动调用cache_delete()精准清理。

数据库查询缓存不是全局开关,必须在每次需要缓存的查询前显式启用,且只对 SELECT 有效;清除时若不指定 URI 段,$this->db->cache_delete_all() 会清空整个数据库缓存目录,不是按驱动隔离。
怎么开启单条 SELECT 查询的缓存
CodeIgniter 的数据库缓存是语句级、非自动的:它不会因为你配置了 cachedir 就默认生效,必须调用 cache_on() 才开始捕获后续的 SELECT 查询结果。
-
$this->db->cache_on()必须放在get()或query()之前,且只影响其后**第一个**SELECT查询(后续查询需重新调用) - 缓存文件生成路径为
application/cache/database/[group_name]+[segment1]/[segment2]/[md5_hash],其中[group_name]默认是default,[segment1]和[segment2]来自当前请求 URI(如/blog/comments) - 不支持缓存
INSERT/UPDATE/DELETE,调用这些方法前未调用cache_off()会导致缓存逻辑异常(但不会报错) - 示例:
$this->db->cache_on(); $query = $this->db->get('users'); // 这条被缓存 $this->db->cache_off(); $query2 = $this->db->get('logs'); // 这条不被缓存
如何精准删除某类数据库缓存文件
误用 cache_delete_all() 容易连带删掉其他控制器的缓存,尤其当多个功能共用相似 URI 结构时。更安全的做法是指定 URI 段来清理。
-
$this->db->cache_delete('blog', 'comments')→ 删除所有匹配/blog/comments*的缓存文件(包括/blog/comments/123、/blog/comments?sort=asc) -
$this->db->cache_delete('admin', 'users')→ 只删/admin/users及其子路径,不影响/api/users - 注意:第二个参数可为空,
$this->db->cache_delete('blog')会删掉整个blog目录下所有缓存,仍有一定范围 - 如果完全不确定 URI 分段,宁可手动进
application/cache/database/查看目录结构,再决定删哪一层
为什么 cache_delete_all() 不总是“清空数据库缓存”
这个方法名有误导性——它其实只清 application/cache/database/ 下的文件,和你用 $this->cache->driver('file') 或 Redis 驱动完全无关。很多人混淆了“数据库查询缓存”和“通用缓存驱动”。
-
$this->db->cache_delete_all():仅删application/cache/database/下所有文件,不管是否过期 -
$this->cache->clean():清的是你配置的缓存驱动(如apc、redis、file),和数据库缓存目录无关 - 两者无自动联动。开了数据库缓存又用了
$this->cache存业务数据,就得分别清理 - 生产环境慎用
cache_delete_all():它会触发全量文件 IO,高并发下可能短暂阻塞 Web 请求
开发阶段最容易忽略的三个细节
缓存机制本身简单,但 CI 的实现方式让几个边界情况特别容易踩坑。
- 缓存依赖完整 URI 路径,
/user?id=1和/user?id=2是两个独立缓存文件,无法通配清除 —— 没有类似cache_delete('user', '*')的语法 - 启用缓存后,修改模型或视图代码不会自动失效缓存,必须手动删文件或调用
delete_cache(),否则看到的永远是旧结果 -
$db['default']['cachedir']必须指向可写目录,且路径末尾**不能带斜杠**(APPPATH.'cache/database'✅,APPPATH.'cache/database/'❌),否则缓存文件写入失败但无任何提示










