【问题标题】:Very slow php update code after adding some data to the database?向数据库添加一些数据后,php 更新代码非常慢?
【发布时间】:2012-08-26 19:05:18
【问题描述】:

我有一个足球梦幻联赛的 php 脚本,有 20 支球队和 400 多名球员被分配到球队,我有 500 个用户。

每个星期都应该为每个球员分配一个积分,这样最终每个用户都会从他的阵型中得到一个总分,这将产生赛季的排名。

第一周点数正常添加,但第二周点数addpont部分变得很慢,第三周点数出现套接字超时错误。

这是我在向用户添加积分时使用的代码:

// Adding Point To the user player list
$sql_user="select * from ".$prev."user LIMIT 0, 100 ";  

$re_user=mysql_query($sql_user);  
while($d_user=mysql_fetch_array($re_user))  
{  
$userID=$d_user['id'];  

  $sql_addpointgroup="select * from ".$prev."addpoint group by weekno order by weekno";  
  $re_addpointgroup=mysql_query($sql_addpointgroup);  
  while($d_addpointgroup=mysql_fetch_array($re_addpointgroup))  
  {     
      $points=0;  
      $sql_addpoint="select * from ".$prev."addpoint where   weekno='".$d_addpointgroup['weekno']."'";  
      $re_addpoint=mysql_query($sql_addpoint);  
      while($d_addpoint=mysql_fetch_array($re_addpoint))  
      {  
        $points=$d_addpoint['points'];  
        $sql_weekstatistic="select * from ".$prev."weekstatistic where   weekno='".$d_addpointgroup['weekno']."' and userID='$userID' and playerID='".$d_addpoint['playerID']."'";  
        $re_weekstatistic=mysql_query($sql_weekstatistic);  
        if(mysql_num_rows($re_weekstatistic)>0)  
        {  
            $sql_update="update ".$prev."weekstatistic set points='$points' where weekno='".$d_addpointgroup['weekno']."' and userID='$userID' and playerID='".$d_addpoint['playerID']."'";  

            mysql_query($sql_update);  
        }  
      }  
}     
}  

我已将每次提交的用户数限制为 100 个用户,即便如此代码仍然很慢。

只有这个代码的缓慢,其他网站部分才能正常工作。

有什么方法可以用其他更快的方式编写代码,或者还有什么我可以做的吗?

非常感谢,

【问题讨论】:

  • 仅供参考,您的查询可能不安全。您不会转义任何数据以用于查询,并且很可能会被黑客入侵。考虑使用 PDO 准备好的查询来避免这个问题。
  • 我想补充一点,如果您不想使用 PDO,您可以使用 real_escape_string() 来防止对您的脚本进行 SQL 注入黑客攻击。这是一个很好的链接,展示了如何使用它。 php.net/manual/en/mysqli.real-escape-string.php
  • 请用解释检查您的查询,并检查您是否使用了正确的索引,没有全表扫描等等。
  • 请不要使用mysql_* 函数编写新代码。它们不再维护,社区已经开始deprecation process。看到 red box 了吗?相反,您应该了解prepared statements 并使用PDOMySQLi。如果你不能决定哪一个,this article 会帮助你。如果你选择 PDO,here is good tutorial

标签: php performance


【解决方案1】:
select * from

希望您知道SELECT 查询中* 的含义。 这意味着ALL COLUMNS。 您不需要每行所有列的值。 在您的查询中具体并仅选择您需要的列。

例如,这个查询:

$sql_weekstatistic="select * from ".$prev."weekstatistic where   weekno='".$d_addpointgroup['weekno']."' and userID='$userID' and playerID='".$d_addpoint['playerID']."'";  

您已经拥有以下价值:

weekno @ $d_addpointgroup['weekno']
userID @$userID
playerID @$d_addpoint['playerID']

基于其他查询。

然而,你仍然使用SELECT * FROM

这是我关于性能和 SQL 的小技巧。

顺便说一句,使用mysql_real_escape_tring() 保护您的查询, 或者,甚至更好的是,按照@lshikawa 的建议,转到mysqliPDO

【讨论】:

【解决方案2】:

除了建议您遵循此线程中其他人的建议外,我不会提及 SQL 注入的问题。说真的 - 如果您要求人们提交个人数据以存储在您的数据库中,您应该保护他们不让这些数据被盗。

您的流程缓慢的原因可能是双重的。

首先,当您只需要一个查询时,您会使用 5 个查询。您正在向数据库询问您用来向其提出更多问题的大量数据 - 在不了解您的架构的情况下,很难为您提供有效的替代品,但类似于:

update ".$prev."weekstatistic 
set      points   = ap.points 
from     weekstatistic ws, 
         addpoint      ap, 
         user          u
where    weekno   = //work out the current weeknumber 
and      userID   = u.userID 
and      playerID = ap.playerID'

这应该实现相同,但只在一个查询中;那应该快得多。

其次,您的表中可能没有正确的索引 - 这是“当我在表中获取更多数据时,我的查询变慢”的典型原因。阅读 EXPLAIN,并添加一些索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 2019-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多