CodeIgniter 无内置数据库连接池,采用按需创建、请求结束即释放的连接机制;可通过启用持久连接、预加载多库、封装连接工厂等方法模拟连接池效果,提升高并发与多库场景性能。

CodeIgniter 本身不内置数据库连接池机制,它采用的是“按需创建、请求结束即释放”的连接管理方式。所谓“连接池”在 CI 中属于伪概念——你无法像 Java 的 HikariCP 或 Laravel 的 PDO 连接复用那样配置最大空闲连接数、自动回收等参数。但通过合理配置和编码技巧,可以模拟出接近连接池的效果,提升多库切换或高并发场景下的稳定性与响应效率。
理解 CI 的数据库连接生命周期
CI 每次调用 $this->load->database()(无论是否显式调用)时,默认会:
- 检查当前是否已存在该连接(基于配置组名);
- 若不存在,则新建一个 PDO 或 mysqli 连接;
- 连接对象被缓存到 CI 的静态资源池中,同一次 HTTP 请求内重复加载同一组不会重建连接;
- 请求结束时,PHP 自动关闭所有打开的数据库连接(无显式销毁逻辑)。
这意味着:单次请求内多次使用 $this->db 是安全且高效的,无需手动“复用”连接;但跨请求不能共享连接,也不存在后台保活或预热机制。
模拟连接池效果的关键配置项
虽然没有真正的连接池,但以下几项配置能显著减少连接开销、避免频繁握手:
-
启用持久连接(慎用)
在database.php对应数据库组中设:'pconnect' => TRUE,
✅ 优点:PHP-FPM 进程复用底层 MySQL 连接,降低 TCP 握手和认证成本。
❌ 风险:可能导致连接泄漏、事务状态残留、字符集错乱,尤其在长生命周期脚本或 CLI 场景下。仅建议在稳定、短平快的 Web 请求中开启,并配合wait_timeout数据库参数调优。 -
关闭调试与查询日志(生产环境必做)
'db_debug' => FALSE, 'save_queries' => FALSE,
减少内存占用和字符串拼接开销,间接提升连接初始化速度。
设置合理的超时与重试
CI 不支持原生 failover 重试,但可通过'failover' => array(...)定义备用服务器(仅限同构主从),故障时自动切换,避免单点阻塞。
动态多库场景下的“软连接池”实践
当应用需频繁切换多个数据库(如 SaaS 租户隔离、读写分离、分析库同步),推荐以下模式:
-
预加载常用连接组
在控制器构造函数或基类__construct()中一次性加载多个库:$this->db_master = $this->load->database('master', TRUE); // 第二个参数 TRUE 返回实例 $this->db_slave = $this->load->database('slave', TRUE); $this->db_log = $this->load->database('log', TRUE);后续操作直接使用
$this->db_slave->get(),避免每次调用load->database()的查找开销。 -
封装连接工厂方法(推荐)
在模型或服务类中统一管理连接获取逻辑:protected function get_tenant_db($tenant_id) { $config = $this->tenant_config_model->get_by_id($tenant_id); return $this->load->database($config, TRUE); // 传数组而非组名 }结合缓存(如 APCu 缓存已生成的 config 数组),可进一步减少配置解析时间。
-
避免在循环中反复 load database
错误示例:foreach ($ids as $id) { $db = $this->load->database('tenant_'.$id, TRUE); // 每次都 new + connect! $db->where('id', $id)->update(...); }正确做法:提取共用连接,或批量操作改用单库事务+IN 查询。
监控与调优建议
- 使用 CI 自带的 Profiler(
$this->output->enable_profiler(TRUE))观察“Database Queries”区块,确认是否出现重复连接或慢查询。 - 查看 MySQL 的
SHOW PROCESSLIST,识别是否存在大量 Sleep 状态连接(说明pconnect开启但未及时清理)。 - 对于 CLI 命令(如定时任务),务必在脚本末尾显式关闭连接:
$this->db->close(); // 防止连接堆积
不复杂但容易忽略。


















