【问题标题】:PDO effective SELECT and INSERTPDO 有效的 SELECT 和 INSERT
【发布时间】:2014-12-21 20:05:46
【问题描述】:

我是PHPPDO 的初学者。

下面的代码可以工作,但是非常非常慢。有什么办法可以提高效率吗?

while() 效率不高,但确实有效。我尝试了其他解决方案,但没有任何效果。

有什么建议吗?

    public function register_new_member(){

        global $bcrypt; 
        global $populera;

        $query = $this->db->prepare("SELECT id, lid, firstname, surname FROM `members`");

        try{
            $query->execute();      
            while ($data = $query->fetch()){

            $id = $data['id'];
            $lid = $data['lid'];

            $username = $populera->create_username($data['firstname'],$data['surname']);    

            //Show data
            echo "<br>Username: ".$username;
            echo "<br>ID: ".$id;
            echo "<br>LID: ".$lid;      

            //Static password - change after login      
            $password = "password";

            //Bcrypt    
            $pass = $bcrypt->generateHash($password);

            //Show data
            echo "<br>Password: ".$pass;


            $query2  = $this->db->prepare("INSERT INTO `login` (`id`, `lid`, `user`, `password`) VALUES (?, ?, ?, ?) ");

            $query2->bindValue(1, $id);
            $query2->bindValue(2, $lid);
            $query2->bindValue(3, $username);
            $query2->bindValue(4, $pass);

            $query2->execute();
            }
            //Success? 
            echo "<br>Saved!";

            }catch(PDOException $e){
                die($e->getMessage());
            }
}

【问题讨论】:

标签: php mysql pdo


【解决方案1】:

哈希函数可能很慢——因为您为所有用户设置了相同的密码,您可以将此计算移出循环。 (它应该很慢,因为哈希通常会重复一些“轮”以使暴力破解变得困难。)

我无法从您的代码中判断您是否对每个哈希使用随机盐。如果你是(而且你应该是),那么这个建议会给你留下许多用相同盐散列的密码。我不确定这有多大风险,因为无论如何您都将它们都设置为相同的值。

我个人会尝试提出一个我没有预设密码的解决方案——例如生成一个随机令牌,我通过电子邮件发送给每个用户,这样他们就可以为自己创建一个新密码。 (无论如何,您可能需要一些东西来让用户重置忘记的密码。)

【讨论】:

    【解决方案2】:

    您不清楚very very slow 的含义。

    您可以尝试使用此查询批量填充您的 login 表。

    INSERT INTO login (id, lid, user)
    SELECT id,
           lid,
           CONCAT(firstname, ' ', surname) AS user
      FROM members
    

    这应该会更新您需要的所有行。

    最后,您必须通过 php 来设置密码。这会将所有空密码或空白密码设置为您的起始密码。

            //Bcrypt    
            $pass = $bcrypt->generateHash($password);
            $query2  = $this->db->prepare("UPDATE login SET password  ? WHERE password IS NULL OR LENGTH(password) = 0");
            $query2->bindValue(1, $pass);
            $query2->execute();
    

    【讨论】:

      【解决方案3】:

      我会为此考虑几个优化:

      1. 在 while 循环之外准备插入(没有必要重新准备,而且成本很高)
      2. 在事务中进行所有插入,如果数据量很大,只需将它们提交较小的块或使用mysql的保存点。

      【讨论】:

        【解决方案4】:

        我认为这里的效率问题是您为第一个查询结果中的每一行运行$query2-&gt;execute()。您可以进行多次插入以提高效率。

        How to insert multiple rows in one query

        【讨论】:

          猜你喜欢
          • 2012-08-22
          • 1970-01-01
          • 2017-12-13
          • 2018-09-02
          • 2012-01-10
          • 2019-09-27
          • 2016-06-10
          • 2018-04-14
          • 2022-12-03
          相关资源
          最近更新 更多