You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter如何用单查询实现带Limit与无Limit的分页?

优化CodeIgniter分页查询:单逻辑复用实现总数+分页数据

这确实是个很实用的优化需求——避免重复执行几乎一样的查询,还能复用逻辑。在CodeIgniter里,我们有两种靠谱的方案来实现你的需求:

方案一:MySQL专属高效方案(推荐,仅一次核心查询逻辑)

利用MySQL的SQL_CALC_FOUND_ROWS和FOUND_ROWS()特性,让数据库在执行分页查询的同时,计算出不带LIMIT的总记录数,不需要重复跑一遍WHERE条件。

优化后的代码如下:

// 构建核心查询逻辑(复用你原有的所有条件)
$this->db->select('SQL_CALC_FOUND_ROWS *'); // 关键:添加SQL_CALC_FOUND_ROWS标记
if (!empty($id)) {
    $this->db->where("id", $id);
}
if (!empty($to)) {
    $this->db->where("to", $to);
}
if ($is_deleted != "") {
    $this->db->where("is_deleted", $is_deleted);
}
if (!empty($from)) {
    $this->db->where("from", $from);
}
if (!empty($priority)) {
    $this->db->where("priority", $priority);
}
$this->db->order_by($orderby, $order);

// 处理分页参数(保持你原有的逻辑)
if ($page < 1) {
    $page = 1;
}
if ($pagesize < 1) {
    $pagesize = 1;
}
$offset = ($page - 1) * $pagesize;

// 1. 执行带LIMIT的查询,获取分页数据
$rows = $this->db->get($this->Table, $pagesize, $offset)->result_array();

// 2. 获取不带LIMIT的总记录数(复用前面查询的计算结果)
$total_result = $this->db->query('SELECT FOUND_ROWS() AS total_records')->row();
$total_records = $total_result->total_records;

原理说明:

  • SQL_CALC_FOUND_ROWS:告诉MySQL在执行当前带LIMIT的查询时,额外计算如果移除LIMIT会返回的总记录数,这个结果会被临时存储。
  • FOUND_ROWS():直接读取刚才存储的总记录数,不需要再重新执行一遍所有WHERE条件的查询,性能提升明显,尤其是当WHERE条件复杂或数据量大时。
  • 所有查询逻辑(WHERE、ORDER BY)只写一次,后续维护只需要修改一处,避免了两次查询逻辑不一致的风险。

方案二:跨数据库兼容方案(逻辑复用,两次查询)

如果你的项目可能切换到非MySQL数据库(比如PostgreSQL、SQL Server),上面的方案就不适用了。这时候我们可以把查询逻辑封装成私有方法,实现逻辑复用,避免重复写条件:

/**
 * 封装查询逻辑的私有方法
 */
private function buildPaginationQuery() {
    $this->db->select('*');
    if (!empty($id)) {
        $this->db->where("id", $id);
    }
    if (!empty($to)) {
        $this->db->where("to", $to);
    }
    if ($is_deleted != "") {
        $this->db->where("is_deleted", $is_deleted);
    }
    if (!empty($from)) {
        $this->db->where("from", $from);
    }
    if (!empty($priority)) {
        $this->db->where("priority", $priority);
    }
    $this->db->order_by($orderby, $order);
}

// 主逻辑
// 1. 获取总记录数(false参数表示不重置查询构建器)
$this->buildPaginationQuery();
$total_records = $this->db->count_all_results($this->Table, false);

// 2. 获取分页数据
$this->buildPaginationQuery();
$rows = $this->db->get($this->Table, $pagesize, $offset)->result_array();

原理说明:

  • 把所有查询条件封装到私有方法中,两次查询都调用这个方法,保证逻辑一致。
  • count_all_results($table, false)中的false参数很关键,它会保留查询构建器中的条件,不会自动重置,这样我们后续可以继续复用相同的条件来查询分页数据。

内容的提问来源于stack exchange,提问作者usman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:52:55