$this->db->save_queries 是 codeigniter 数据库类的内存记录开关,默认为 true,开启后会持续缓存每次查询的 sql、参数、耗时等信息至脚本结束,易导致内存溢出;需在大批量操作前手动设为 false。

因为默认开启了查询记录($this->db->save_queries),每条 SQL 和执行时间都被保留在内存里,不释放。
CI 的 save_queries 是什么
这是 CodeIgniter 数据库类内置的一个开关,默认为 TRUE。只要开启,每次调用 query()、get()、insert() 等方法,框架就会把原始 SQL 字符串、绑定参数、执行耗时、影响行数等信息存进一个数组:$this->db->queries 和 $this->db->query_times。
这个设计本意是方便调试——比如在开发环境看「到底执行了哪些语句」「哪条慢」。但它不会自动清理,也不按需释放,所有记录会一直堆在内存里直到脚本结束。
常见错误现象:
- CLI 下跑百万级循环插入,报
Fatal error: Allowed memory size of XXX bytes exhausted - Web 请求中分页导出 10 万条数据,响应超时或直接 500
-
memory_get_usage()在循环中持续上涨,且不回落
什么时候必须关掉 save_queries
不是所有场景都需要关,但以下情况建议立即关闭:
- CLI 脚本做大批量数据导入、清洗、同步(如每天定时跑的 cron)
- 控制器中用循环执行上百次以上数据库操作(比如遍历用户发通知)
- 使用
get()+result()拉取大量结果后还要做 PHP 层处理 - 部署在内存受限环境(如 512MB RAM 的轻量服务器)
关的方法很简单,在操作前加一行:
$this->db->save_queries = FALSE;
注意:这行要放在任何数据库调用之前,且对当前请求/脚本生命周期生效。不需要全局配置,也不影响其他请求。
关了之后会影响调试吗
只影响「回溯历史查询」,不影响日志、错误提示或实际执行。你仍然能看到:
- 数据库连接失败的异常
- SQL 语法错误的报错(
db_debug = TRUE时) - 用
log_message('debug', ...)手动记录的关键步骤 - 第三方工具(如 Laravel Telescope 替代品或自研监控)捕获的慢查询
真正需要查某次具体 SQL 时,更可靠的方式是:
- 临时打开
save_queries+ 加日志输出$this->db->last_query() - 用 MySQL 的
general_log或slow_query_log - 在关键位置用
var_dump($sql)或写入文件调试
最常被忽略的一点:这个设置不继承、不跨请求、不靠配置文件生效——它就是一个运行时属性。很多人改了 database.php 里的缓存路径,却忘了在脚本里手动关掉 save_queries,结果内存照样爆。











