ci框架大数据分页优化需禁用查询日志、改用游标分页、id分批缓存及前端约束页码;禁用$this->db->save_queries、基于主键游标查询、redis缓存id列表、限制page≤200并启用懒加载。

CI框架处理大数据量分页时,内存暴涨、响应缓慢、甚至脚本崩溃,根本原因不在数据本身,而在框架默认行为与查询方式的叠加效应。关键要切断“无用记录”和“低效扫描”的双重开销。
关闭数据库查询日志记录
CI默认开启 $this->db->save_queries,每条SQL及其执行时间都被缓存到内存中。百万级循环分页时,这些日志会吃掉数百MB内存,且完全无业务价值。
- 在分页逻辑开始前加一行:
$this->db->save_queries = FALSE; - 如需临时调试,可仅在开发环境开启,生产环境必须禁用
- 该设置不影响SQL执行,只停止日志收集,零风险、立竿见影
改用游标分页(推荐用于后端API)
传统 LIMIT offset, size 在偏移量大时性能断崖式下跌,因为MySQL仍要扫描跳过的所有行。游标分页基于上一页最后一条记录的主键值推进,避免全表扫描。
- 首次请求:
SELECT * FROM orders WHERE status = 1 ORDER BY id ASC LIMIT 50 - 后续请求:
SELECT * FROM orders WHERE status = 1 AND id > 123456 ORDER BY id ASC LIMIT 50 - CI中可封装为方法:
$this->db->where('id >', $last_id)->order_by('id')->limit(50) - 要求:排序字段必须有索引、不可为空、全局唯一(主键最佳)
分批处理 + 手动分页缓存
对导出、后台报表等非实时场景,不建议每次翻页都查库。可先将符合条件的数据ID批量取出,存入Redis或临时表,再按ID分页读取详情。
- 第一步:查出全部匹配的主键ID(例如
SELECT id FROM logs WHERE created_at > '2025-01-01'),用batch_insert或 Redis List 存储 - 第二步:按页取ID段,再用
WHERE id IN (...)查详情(注意IN数量限制,单次不超过500) - 优势:主键查询极快;ID列表可设置过期时间;支持并发读取不同页
前端配合:禁用深度跳页 + 启用懒加载
用户翻到第1000页毫无意义,反而拖垮数据库。应在业务层主动约束,同时降低首屏压力。
- CI控制器中校验:
if ($page > 200) { show_error('超出允许页码范围'); } - 列表页启用滚动懒加载,初始只加载前20条,滚动到底部再通过AJAX拉取下一批(带游标参数)
- 搜索框强制添加时间范围、状态等过滤条件,避免全表扫描











