【问题标题】:How to make my php code faster?如何让我的 php 代码更快?
【发布时间】:2017-07-03 08:54:16
【问题描述】:

我在服务器端使用 php 来管理 MySQL 数据。 我必须请求一个提供用户列表的 API。我需要检查每个用户是否在数据库中。 如果是,我会更新他的信息。 如果没有,我将他插入数据库。

问题是每次都有超过 2000 多个用户,我的 PHP 代码真的很慢(有时我得到 504 Gateway Time-out)。 我们很快就会拥有更多用户。

如何让我的代码更快? php可以吗?

改进后编辑我的codeV3:

    $userList = getFromAPI();

      foreach ($userList as $userId){

        $db = dbConnect();


  $tagList = implode(",", $user["tagid_list"]);



          $query = $db->prepare(
      "INSERT INTO USERS(id, name, group) VALUES(:id, :name, :group)
       ON DUPLICATE KEY UPDATE name=values(name), group=values(group)"
          );

          $query->execute([
        "id"=>$id,
        "name"=>$name,
        "group"=>$group
          ]);
        }

【问题讨论】:

  • 我猜你的问题是数据库语句。
  • 您是否考虑过select id from users where id = :userid 并查看它是否返回一行?或者,如何舍弃这部分内容,改为使用insert into users ... on duplicate key update ...
  • 在检查数据库中是否存在特定用户时不要获取每个用户,修改您的选择以通过您要检查的 id 选择....然后您也可以消除它array_column() 和 in_array() 检查
  • @NiettheDarkAbsol 我用我的新代码更新我的帖子,并在重复键更新时插入。但它似乎不起作用。 “id”列是我的主键。
  • @MarkBaker 感谢您的建议,我已经修改了选择并放了一个“!empty()”来检查是否有结果。如果您有任何改进,请使用我的新代码编辑帖子

标签: php mysql


【解决方案1】:

也许尝试将$db = dbConnect(); 放在您的 foreach 之外? 不知道是否需要在每个循环中打开连接。这也可能很耗时。

【讨论】:

  • 这取决于该函数的作用。如果它返回一个单例,那没关系(即使将它放在外面仍然更有意义)。如果它实际上在每次迭代中都连接,那么是的,那肯定很重要。不过,还有其他更明显的因素会影响该代码的速度。
  • 您看到的 foreach 在另一个函数中。所以我应该把 $db = dbConnect 放在这个函数之外,然后把 $db 放在这个函数的参数中?
  • 是的,这是可能的。你也可以在question
【解决方案2】:

您可以为此使用单个查询:

INSERT INTO users (id, name)
VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Cecil')
ON DUPLICATE KEY UPDATE name = VALUES(name);

简而言之:您插入新行,但如果已经存在一个(键重复),则改为更新它。您可以在循环中构建插入值,这样您最终得到一个查询而不是 4000+。

阅读更多here

【讨论】:

  • $query = $db->prepare("INSERT INTO USERS(id, name, group) VALUES(:id, :name, :group) ON DUPLICATE KEY UPDATE name=:name, group= :团体”);。似乎不起作用。
  • 太糟糕了!也许如果您提供一些有关问题的详细信息、您收到的错误消息等,那么我可以尝试猜测问题所在。
  • 没有错误信息,但是数据没有插入或更新。
  • 尝试按照我建议的方式构建您的查询,在更新部分使用VALUES(name)VALUES(group)。不要重复相同的参数两次。
  • 好的,完成了,但是仍然没有错误消息,也没有数据插入或更新。 (编辑帖子)
【解决方案3】:

首先,从 foreach lopp 中获取数据库中的所有用户 ID,并将其缓冲在某个变量中。应该会更好。

【讨论】:

  • 谢谢,我将 fetch all users 替换为 select where id=id。好点了吗?
  • 我会将fetchall 放在foreach 之前,并且不会像@carl-kroeger-ihl 注意到的那样在每个周期都连接到数据库。
  • 我删除了选择,找到了另一种方法来做到这一点。对于 dbConnect() 问题是您在 foreach 中看到的所有代码都在一个函数中。所以我需要在参数中传输db?
  • 我会像你说的那样(连接 $db 作为函数参数)。
猜你喜欢
  • 2017-08-28
  • 2017-07-11
  • 1970-01-01
  • 2015-06-30
  • 2021-02-10
  • 2011-12-07
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
相关资源
最近更新 更多