使用PHP for循环进行SQL更新花费的时间太长

使用PHP for循环进行SQL更新花费的时间太长,php,mysql,sql,sql-update,Php,Mysql,Sql,Sql Update,我正在尝试使用PHP for循环更新我的表,但这将花费太长的时间。我的桌子上确实有20万人。当我打开php文件时,浏览器会自动运行:)当我打开phpMyAdmin时,我可以看到它工作,但速度非常慢 有没有一种方法可以直接在phpMyAdmin中使用SQL完成完全相同的事情 for ($a = 0; $a < 200000; $a++) { $rand = mt_rand(10000000, 99999999); // checks whether the same url

我正在尝试使用PHP for循环更新我的表,但这将花费太长的时间。我的桌子上确实有20万人。当我打开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();
    }
}
($a=0;$a<200000;$a++)的
{
$rand=mt_rand(100000009999999);
//检查是否存在相同的url
$sec=“从person中选择person\u url=“$rand”;
$result=$sqli->query($sec);
$row=$result->fetch_assoc();
$finish=$row['person_url'];
如果($finish==false){
$sql=$sqli->prepare(“更新人员设置人员url='$rand',其中人员id='$a'”);
$sql->execute();
}
}

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

$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();
    }
}
$sql1=$sqli->prepare(“从person-WHERE-person\u-url=?”中选择person\u-url”);
$sql1->bind_参数('s',$rand);
$sql2=$sqli->prepare(“更新人员设置人员url=?其中人员id=?”;
$sql2->bind_参数('si',$rand,$a);
对于($i=0;$a<200000;$a++){
$rand=mt_rand(100000009999999);
//检查是否存在相同的url
$sql1->execute();
$sql1->store_result();
如果($sql1->num\u rows==0){
$sql2->execute();
}
}

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

$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();
    }
}
$sql1=$sqli->prepare(“从person-WHERE-person\u-url=?”中选择person\u-url”);
$sql1->bind_参数('s',$rand);
$sql2=$sqli->prepare(“更新人员设置人员url=?其中人员id=?”;
$sql2->bind_参数('si',$rand,$a);
对于($i=0;$a<200000;$a++){
$rand=mt_rand(100000009999999);
//检查是否存在相同的url
$sql1->execute();
$sql1->store_result();
如果($sql1->num\u rows==0){
$sql2->execute();
}
}

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

您只需使用

update person set person_url = (cast(rand()*89999999 as signed)+10000000);
您可能会在person_url字段中获得重复条目,您需要通过某种方式来解析这些条目

执行此操作的一种方法是将
person\u url
列设置为unique,并使用带有
ignore
的查询和不同的
where
子句:

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

这可能只需一次就可以完成任务,但如果无法完成,请重复运行,直到完成为止。您必须使用两个或三个以上的过程,这将是非常不幸运的,而且它仍然可能比使用PHP手动检查唯一性快得多。

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

您只需使用

update person set person_url = (cast(rand()*89999999 as signed)+10000000);
您可能会在person_url字段中获得重复条目,您需要通过某种方式来解析这些条目

执行此操作的一种方法是将
person\u url
列设置为unique,并使用带有
ignore
的查询和不同的
where
子句:

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

这可能只需一次就可以完成任务,但如果无法完成,请重复运行,直到完成为止。您必须使用两个或三个以上的过程,这将是非常不幸运的,而且它仍然可能比使用PHP手动检查唯一性快得多。

您应该只准备一次语句,然后在循环中执行它。可能重复的语句应该只准备一次,然后在循环中执行它。他的代码的可能副本确保它不会创建任何重复的
person\u url
。你的不是。感觉像是一个工作,所以我只需添加一个唯一的键,更改上面的内容以检查person\u url是否已创建,然后手动运行几次,当它遇到重复项时会失败,但手动执行几次,它应该会填入所有值。我尝试了你的答案,但得到了一个MySQL错误#1064-您的SQL语法有错误;请查看与MySQL服务器版本对应的手册,以了解在第1行使用接近“整数)+10000000)”的正确语法,使用
FLOOR()
而不是
CAST()
。我的错误-应该使用
CAST(?as SIGNED)
而不是
CAST(?as integer)
<代码>地板()可能比
CAST()
更好。(感谢@Barmar)他的代码确保它不会创建任何重复的
个人url
。你的不是。感觉像是一个工作,所以我只需添加一个唯一的键,更改上面的内容以检查person\u url是否已创建,然后手动运行几次,当它遇到重复项时会失败,但手动执行几次,它应该会填入所有值。我尝试了你的答案,但得到了一个MySQL错误#1064-您的SQL语法有错误;请查看与MySQL服务器版本对应的手册,以了解在第1行使用接近“整数)+10000000)”的正确语法,使用
FLOOR()
而不是
CAST()
。我的错误-应该使用
CAST(?as SIGNED)
而不是
CAST(?as integer)
<代码>地板()可能比
CAST()
更好。(谢谢@Barmar)