【问题标题】:SQL update using PHP for loop takes too long使用 PHP for 循环的 SQL 更新耗时太长
【发布时间】:2015-01-11 22:40:44
【问题描述】:

我正在尝试使用 PHP for 循环更新我的表,但它需要很长时间才能工作。我的桌子上真的有200,000 人。当我打开 php 文件时,浏览器会自动挂起 :) 当我打开 phpMyAdmin 时,我可以看到它可以工作,但速度很慢。

有没有办法直接在 phpMyAdmin 中使用 SQL 做同样的事情?

for ($a = 0; $a < 200000; $a++) {
    $rand = mt_rand(10000000, 99999999);
    // checks whether the same url exists or not
    $sec = "SELECT person_url FROM person WHERE person_url = '$rand'";
    $result = $sqli->query($sec);
    $row = $result->fetch_assoc();
    $finish = $row['person_url'];
    if ($finish == false) {
        $sql = $sqli->prepare("UPDATE person SET person_url = '$rand' WHERE person_id = '$a'");
        $sql->execute();
    }
}

【问题讨论】:

标签: php mysql sql sql-update


【解决方案1】:

您似乎正在使用特定范围内的随机数更新表中的每一行。您根本不需要进行任何 PHP 处理。

你可以简单地更新表格

update person set person_url = (cast(rand()*89999999 as signed)+10000000);

您可能会在 person_url 字段中获得重复条目,您需要通过某种方式解决这些条目。

这样做的一种方法是将person_url 列设置为唯一,并将查询与ignore 和不同的where 子句一起使用:

update ignore person set person_url = (cast(rand()*89999999 as signed)+10000000)
    where person_url is null;

这可能会一次性完成这项工作,但如果没有,请重复运行它,直到完成为止。如果你不得不使用超过两到三遍,那你会很不幸,而且它仍然可能比使用 PHP 手动检查唯一性要快得多。

【讨论】:

  • 他的代码确保不会创建任何重复的person_url。你的没有。
  • 感觉像是一份工作,所以我只添加一个唯一键,更改上面的内容以检查是否创建了 person_url,然后手动运行几次,它会失败点击重复,但手动执行几次,它应该填写所有值
  • 我尝试了您的答案,但遇到了 MySQL 错误。 #1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的“integer)+10000000)”附近使用正确的语法
  • 使用FLOOR() 而不是CAST()。
  • 我的错误 - 应该使用 cast(??? as SIGNED) 而不是 cast(??? as INTEGER)。无论如何,FLOOR() 可能是比CAST() 更好的选择。 (感谢@Barmar)
【解决方案2】:

准备循环外的语句并使用绑定参数。

$sql1 = $sqli->prepare("SELECT person_url FROM person WHERE person_url = ?");
$sql1->bind_param('s', $rand);
$sql2 = $sqli->prepare("UPDATE person SET person_url = ? WHERE person_id = ?");
$sql2->bind_param('si', $rand, $a);
for ($i = 0; $a < 200000; $a++) {
    $rand = mt_rand(10000000, 99999999);
    // checks whether the same url exists or not
    $sql1->execute();
    $sql1->store_result();
    if($sql1->num_rows == 0) {
        $sql2->execute();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    相关资源
    最近更新 更多