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

如何在CodeIgniter中批量查询多ID数据并展示分组结果

优化CodeIgniter模型的N+1查询问题

你的问题是典型的N+1查询性能问题——先查一次table0得到N条数据,然后循环每条数据查一次table1,导致额外N次数据库请求。咱们可以通过批量查询+结果映射的方式,把查询次数降到2次,同时完全兼容原有视图的展示逻辑。

重构后的模型函数

替换你原来的get_quick_navi_menu函数,代码如下:

function get_quick_navi_menu($q_code) {
    // 第一步:查询table0的基础数据
    $this->db->select("*");
    $this->db->where('q_id', $q_code);
    $this->db->from("table0");
    $q = $this->db->get();
    $final = array();

    if ($q->num_rows() > 0) {
        $table0_rows = $q->result();
        // 提取所有需要查询的table1的id,组成数组
        $table1_ids = array_column($table0_rows, 'id');
        
        // 第二步:批量查询table1的所有匹配数据
        $this->db->select("*");
        $this->db->from("table1");
        $this->db->where_in("id", $table1_ids); // 使用where_in替代循环的where
        $table1_q = $this->db->get();
        
        // 把table1的结果按id分组,方便后续快速匹配
        $table1_groups = array();
        if ($table1_q->num_rows() > 0) {
            foreach ($table1_q->result() as $t1_row) {
                if (!isset($table1_groups[$t1_row->id])) {
                    $table1_groups[$t1_row->id] = array();
                }
                $table1_groups[$t1_row->id][] = $t1_row;
            }
        }
        
        // 第三步:把table1的结果映射到对应的table0行上
        foreach ($table0_rows as $row) {
            // 如果当前table0的id有对应的table1数据,赋值给children
            if (isset($table1_groups[$row->id])) {
                $row->children = $table1_groups[$row->id];
            }
            array_push($final, $row);
        }
    }

    return $final;
}

优化说明

  1. 查询次数从N+1降到2次:

    • 第一次查询table0获取所有符合条件的行
    • 第二次用WHERE IN批量查询table1,只会生成一条类似这样的SQL:
      SELECT * FROM `table1` WHERE `id` IN ('17','20','21','22','23')
      
  2. 结果映射保持原有结构:
    通过array_column提取id数组,再把table1的结果按id分组,最后遍历table0的行时直接匹配对应分组,这样生成的$final数组结构和你原来的完全一致,视图代码不需要做任何修改,直接就能正常展示分组结果。

  3. 性能提升明显:
    当table0返回的行数越多,优化效果越显著——减少了数据库连接开销和重复查询的资源消耗。

验证效果

你可以在模型里添加echo $this->db->last_query();在$table1_q = $this->db->get();之后,就能看到生成的批量查询SQL,确认是你想要的IN形式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:39:46