Php 如果未更新,请插入MySQL

Php 如果未更新,请插入MySQL,php,mysql,sql,Php,Mysql,Sql,我在MySQL中有三个表 wi_indv_training(trn_id,ind_id,is_deleted) wi_trn_org(trn_id,grp_id,is_deleted) wi_indv_org(ind_id,grp_id,is_deleted) 在这里,可以将多个组分配给由wi_trn_org表处理的培训。 可以将多个个人分配给多个组。许多人都参与了培训。在这里,我们得到的信息是,个人已经与团体相关联。 现在,在将一个组插入培训时,该组中的个人必须与培训相关联。给定培训中可能已

我在MySQL中有三个表

wi_indv_training(trn_id,ind_id,is_deleted)
wi_trn_org(trn_id,grp_id,is_deleted)
wi_indv_org(ind_id,grp_id,is_deleted)
在这里,可以将多个组分配给由wi_trn_org表处理的培训。 可以将多个个人分配给多个组。许多人都参与了培训。在这里,我们得到的信息是,个人已经与团体相关联。 现在,在将一个组插入培训时,该组中的个人必须与培训相关联。给定培训中可能已经有组和个人(部分或全部)标记为is_deleted=yes

现在,在插入时,我想用is_deleted=no标记已删除的组和培训中的个人,如果数据已经在各自的表中,则应将数据作为新数据插入。为此,我实现了以下性能非常缓慢的方法:

foreach ($grp_id as $key => $value) {
    # code...
    $rs=$this->db->pdoQuery("SELECT * FROM wi_trn_org 
                             WHERE trn_id='$trn_id' 
                             AND grp_id='$value'")->results();            
    if(count($rs)>0)
    {
        $this->db->pdoQuery("UPDATE wi_trn_org SET is_deleted=0 
                            WHERE trn_id='$trn_id' AND grp_id='$value'");
        $grp_indv=$this->db->pdoQuery("SELECT ind_id 
                                       FROM wi_indv_org 
                                       WHERE grp_id='$value' 
                                       AND is_deleted=0")->results();
        foreach ($grp_indv as $ke => $va) 
        {
            $ind_id=$va['ind_id'];
            $rows=$this->db->pdoQuery("SELECT * FROM wi_indv_training 
                                      WHERE trn_id='$trn_id' 
                                      AND ind_id='$ind_id'")->results();
            if(count($rows)>0)
            {
                $this->db->pdoQuery("UPDATE wi_indv_training 
                                     SET is_deleted=0,indv_source='Group' 
                                     WHERE trn_id='$trn_id' 
                                       AND ind_id='$ind_id'");
            }
            else
            {
                $this->db->insert("wi_indv_training",
                                   array("ind_id"=>$ind_id,
                                         "indv_source"=>'Group',
                                         "trn_id"=>$trn_id,
                                         "attendance"=>"yes",
                                         "active"=>"yes"));
            }                
        }
    }
    else
    {
        $this->db->insert("wi_trn_org",array('trn_id'=>$trn_id,'grp_id'=>$value));
        $grp_indv=$this->db->pdoQuery("SELECT ind_id 
                                       FROM wi_indv_org 
                                       WHERE grp_id='$value' 
                                       AND is_deleted=0")->results();
                foreach ($grp_indv as $ke => $va) 
                {
                    $ind_id=$va['ind_id'];
                    $rows=$this->db->pdoQuery("SELECT * 
                                               FROM wi_indv_training 
                                               WHERE trn_id='$trn_id' 
                                               AND ind_id='$ind_id'")->results();
                    if(count($rows)>0)
                    {
                        $this->db->pdoQuery("UPDATE wi_indv_training 
                                             SET is_deleted=0,
                                                 indv_source='Group' 
                                             WHERE trn_id='$trn_id' 
                                               AND ind_id='$ind_id'");
                    }
                    else
                    {
                        $this->db->insert("wi_indv_training",
                                          array("ind_id"=>$ind_id,
                                                "indv_source"=>'Group',  
                                                "trn_id"=>$trn_id,
                                                "attendance"=>"yes",
                                                "active"=>"yes"));
                    }                
                }
            }
        }

有谁能帮助您了解性能增强的最佳算法吗?

这里的主要问题是您在一个循环中有多个查询:

foreach ($grp_id as $key => $value) {
            # code...
            $rs=$this->db->pdoQuery("SELECT * FROM wi_trn_org WHERE trn_id='$trn_id' AND grp_id='$value'")->results();            
...
}
每个SQL查询都会受到性能影响,因此,如果循环运行1000次,那么性能瓶颈已经达到1001次


解决这个问题的方法是将循环内的查询重新构造为循环外查询的一部分。第一个查询可以重写为与原始查询的联接,这可能会为您提供足够的性能来解决问题。如果这还不够的话,你可以把所有这些都变成一个整体

我研究并找到了我的问题的解决方案,即

        $this->db->pdoQuery("UPDATE wi_trn_org SET is_deleted=1 WHERE trn_id='$trn_id'");
        $this->db->pdoQuery("UPDATE wi_indv_training SET is_deleted=1 WHERE trn_id='$trn_id'");
        $this->db->pdoQuery("INSERT INTO wi_trn_org( trn_id, grp_id ) SELECT $trn_id AS trn_id, grp_id FROM wi_group WHERE grp_id IN ($grp) AND grp_id NOT IN (SELECT DISTINCT (grp_id) FROM wi_trn_org)");
        $this->db->pdoQuery("UPDATE wi_trn_org SET is_deleted=0 WHERE trn_id='$trn_id' AND grp_id IN ($grp)");
        $this->db->pdoQuery("INSERT INTO wi_indv_training( ind_id, trn_id ) SELECT ind_id, $trn_id AS trn_id FROM wi_indv_org WHERE grp_id IN ($grp) AND ind_id NOT IN ( SELECT DISTINCT (ind_id) FROM wi_indv_training WHERE trn_id =$trn_id)");
        $this->db->pdoQuery("UPDATE wi_indv_training SET is_deleted=0,indv_source='Group',attendance='yes',active='yes' WHERE trn_id='$trn_id' AND ind_id IN (SELECT DISTINCT(ind_id) FROM wi_indv_org WHERE grp_id IN ($grp))");

这在一定程度上为我提供了性能增强的解决方案。这个算法真的提高了查询性能吗?

请您用例子详细说明一下。我尝试使用插入到。。。在重复密钥更新时。但是我无法得到结果。您是否按照我的建议执行了:尝试从循环中取出第一条SQL SELECT语句?那有用吗?这比试图解决整个问题要简单——这取决于您的数据库大小,这可能就足够了。这减少了循环中多个SELECT查询的开销,从而减少了时间延迟。让我们看看。你说你有一些表现。您发布了一些查询。根据你写的,结果是你得到了性能。因此,唯一可能的逻辑结论是上述代码确实提高了性能。问题是,您了解幕后发生的事情吗?以及数据库是如何针对性能进行调整的?是的,我了解幕后发生的事情。