如何避免PHP / MYSQL中的指数减速?

时间:2014-07-02 19:02:05

标签: php mysql optimization

我是基于在线浏览器的游戏的拥有者,该游戏有大约300名玩家注册。我编写了一个脚本来检测作弊者,但问题是所述脚本中的查询数量将呈指数级增长。

它的工作原理如下:

  1. 发送获取玩家信息的查询。
  2. 在查询内部,运行另一个获取每个玩家信息的查询。
  3. 所以基本上我正在运行一个获取每个玩家姓名和信息的查询,并且在该查询内部我运行另一个查询以从其他玩家那里获取信息。我用它来比较和删除作弊者。

    问题是,由于我有300名玩家,我必须为每位玩家运行300次查询。这是90,000个查询。如果我达到1,000名玩家,则会有1,000,000个查询。必须有更好的方法来做到这一点。

    我的代码:

     <?php
        require '../connect.php';
    
        $rulerinfo = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players");
            while ($rulerinfo2 = $rulerinfo->fetch_assoc()) {
                $id = $rulerinfo2['id'];
                $rulername = $rulerinfo2['rulername'];
                $nationname = $rulerinfo2['nationname'];
                $alliance = $rulerinfo2['alliance'];
                $email = $rulerinfo2['email'];
                $dateregister = $rulerinfo2['dateregister'];
                $useragent = $rulerinfo2['user_agent'];
                $lastseen = $rulerinfo2['lastseen'];
                $password = $rulerinfo2['password'];
    
        $playerinfo = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password  FROM players WHERE id != '$id'");
            while ($playerinfo2 = $playerinfo->fetch_assoc()) {
                $id2 = $playerinfo2['id'];
                $rulername2 = $playerinfo2['rulername'];
                $nationname2 = $playerinfo2['nationname'];
                $alliance2 = $playerinfo2['alliance'];
                $email2 = $playerinfo2['email'];
                $dateregister2 = $playerinfo2['dateregister'];
                $useragent2 = $playerinfo2['user_agent'];
                $lastseen2 = $playerinfo2['lastseen'];
                $password2 = $playerinfo2['password'];
    
                $rulerdistance = levenshtein($rulername, $rulername2);
                $nationdistance = levenshtein($nationname, $nationname2);
                $emaildistance = levenshtein($email, $email2);
                $agentdistance = levenshtein($useragent, $useragent2) / 2;
    
                $totaldistance = $rulerdistance + $nationdistance + $emaildistance + $agentdistance;
    
                if ($password == $password2) {
                    $totaldistance = $totaldistance - 20;
                }
    
                if ($totaldistance < 0) {
                    $totaldistance = 0;
                }
    
    
            }
    
            }
    ?>
    

1 个答案:

答案 0 :(得分:1)

您应该只进行一次查询,将其放入数组并从那里开始使用它。我没有看到需要两次进行几乎相同的查询。第二次在数组中循环,然后检查id是否与当前的id不同。

$res = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players");

$array=array();
while ($row = $res->fetch_assoc()) {
   $array[] = $row;
}

for($i=0; $i<count($array);$i++) {
   for($j=0; $j<count($array); $j++) {
      if ($i != $j) {
         // Call your functions
         $rulerdistance = levenshtein($array[$i]['rulername'], $array[$j]['rulername']);
         ...
      }
   }
}