【问题标题】:page loading long time due to join query inside for loop由于在 for 循环中加入查询,页面加载时间很长
【发布时间】:2019-06-24 14:57:57
【问题描述】:

我已经使用下面的代码创建了一个在页面中显示记录的功能,但是由于加入查询,页面需要很长时间才能加载。有人可以找到问题并提供解决方案吗?

public function baleList($program_id) {
        $this->db->select('id');
        $this->db->from(GIN_PROCESS);
        $this->db->where('ginner_id', $this->prscr_id);
        $this->db->where('program', $program_id);
        $this->db->order_by('id', 'DESC');
        $result = $this->db->get()->result_array(); 
        $id_array = array_column($result, 'id');
        $bales_list = array(); 
        foreach ($id_array as $id) {
            $this->db->select('gp.id, gp.lot_no, SUM(gb.weight) AS weight, SUM(gb.staple) AS staple, SUM(gb.mic) AS mic, SUM(gb.strength) AS strength, SUM(gb.trash) AS trash, gb.color_grade');
            $this->db->from(GIN_BALES . ' gb');
            $this->db->join(GIN_PROCESS . ' gp', 'gp.id=gb.process_id');
            $this->db->where('gb.process_id', $id);
            $this->db->where('gb.sold_status', 0);
            $lot_details = $this->db->get()->result(); 

            if (count($lot_details) > 0) {
                $this->db->select('*');
                $this->db->from(GIN_BALES);
                $this->db->where('sold_status', 0);
                $this->db->where('process_id', $id);
                $bales = $this->db->get()->result();
                if (count($bales) > 0) {
                    $lot_details[0]->bales = $bales;
                    $bales_list[] = $lot_details[0];
                }
            }
        }
        return $bales_list;
    }

这个内部查询有什么单独的功能吗?

ginprocess

ginbale

【问题讨论】:

  • 查询也很可能导致给出无效结果,因为在不使用 GROUP BY 的情况下不允许将聚合列 (SUM()) 与非聚合列混合,因为非聚合列是不确定的(随机).. 见manual 那里提到了。
  • 但是这个函数运行并显示结果。数据库记录数增加后,出现这个加载问题。
  • 更多信息: 1. 选择 id FROM gin_process WHERE ginner_id = '74' AND program = '5' ORDER BY id DESC 2. 选择 gp .id, gp.lot_no, SUM(gb.weight) 作为重量,SUM(gb.staple) 作为订书钉,SUM(gb.mic) 作为麦克风,SUM(gb.strength) 作为强度,SUM (gb.trash) 作为垃圾,gb.color_grade FROM gin_bales gb JOIN gin_process gp 开启 gp.id@HER@987654344456.@987675444444456.@987675444444456gp ON gp.id@HER process_id = '1134' AND gb.sold_status =0 3. 选择 * FROM gin_bales WHERE sold_status =0 AND process_id = '1134'
  • 如果 sql_mode ONLY_FULL_GROUP_BY 被禁用,它会运行,但这并不意味着它以正确的结果运行,因为结果很可能是无效的,因为 SQL 无效......请参阅Why should I provide a Minimal Reproducible Example for a very simple SQL query? 提供示例数据和预期结果..如果没有我们无法帮助您优化这一点..我们还需要问题中涉及的每个表的表结构 (SHOW CREATE TABLE table)
  • 我在上面的描述中添加了图片供参考

标签: php mysql codeigniter


【解决方案1】:

嗯,执行 n 次查询肯定是性能杀手。尝试添加“GROUP BY gb.process_id”,删除循环本身并使用“WHERE gb.process_id IN ($id_array)”。您可能需要在您的选择中使用“ANY_VALUE()”来选择没有最小/最大/等的列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    相关资源
    最近更新 更多