Php 使用mySQL更新1000行的最有效方法是什么?

Php 使用mySQL更新1000行的最有效方法是什么?,php,mysql,leaderboard,Php,Mysql,Leaderboard,我正在做一个项目,到目前为止,它有7000多行排行榜数据,其中包括姓名、id、分数和排名。它在不断扩展,我目前遇到了一个障碍,每次有人发布新的分数时,服务器都试图更新所有内容,但服务器超时 目前,我正在使用PDO和一个结合了循环执行调用的查询。在一个mySQL查询中是否有一种更快的方法来实现这一点?或者,您对如何处理更新排行榜有何建议 $stmt = $dbh->prepare("SELECT * FROM high_scores ORDER BY score DESC");

我正在做一个项目,到目前为止,它有7000多行排行榜数据,其中包括姓名、id、分数和排名。它在不断扩展,我目前遇到了一个障碍,每次有人发布新的分数时,服务器都试图更新所有内容,但服务器超时

目前,我正在使用PDO和一个结合了循环执行调用的查询。在一个mySQL查询中是否有一种更快的方法来实现这一点?或者,您对如何处理更新排行榜有何建议

    $stmt = $dbh->prepare("SELECT * FROM high_scores ORDER BY score DESC");
    $stmt->execute();

    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $results = $stmt->fetchAll();

    //

    $numItems = count($results);

    // is this OK or a no-no?

    try {

        $stmt = $dbh->prepare("UPDATE high_scores SET rank = :rank WHERE uid = :uid");

        for($i=0; $i<$numItems; $i++){
            $rank = $i + 1;
            $uid = $results[$i]['uid'];
            $stmt->execute(array(':rank' => $rank, ':uid' => $uid));
        }

        return true;

    } catch (PDOException $e) {
        echo($e->getMessage()); 
    }

我想你可以通过一个查询,比如

UPDATE high_scores a SET rank = (SELECT count(uid) + 1 FROM high_scores b WHERE b.score > a.score) ORDER BY score DESC

不幸的是,我现在没有MySQL来尝试这一点,所以如果结果证明这根本不可行,我将删除它。

我认为您可以通过一个查询来完成这一切,比如

UPDATE high_scores a SET rank = (SELECT count(uid) + 1 FROM high_scores b WHERE b.score > a.score) ORDER BY score DESC

不幸的是,我现在没有MySQL来尝试这一点,所以如果结果证明这根本不可行,我将删除它。

快速浏览一下MySQL的“案例”

不过,你很可能会在这里找到答案:

实际上,您有一个SQL行,它有自己的内部switch语句。您只需告诉它当给定字段具有特定值时该怎么做。在上面的链接中,它的意思是

When `id` is 1, then set the value to 12. 
When `id` is 2, then set the value to 42. 
etc.
您唯一关心的可能是7000多行

但是,使用PHP,我将数据放在一个数组中,然后使用array_slice,一次获取200/300条记录,设置SQL行,然后执行。然后获取下一个200/300记录并重复,直到它到达PHP数组的末尾

编辑:
但请记住,只有当您基于另一个字段(如密钥)更新一个字段时,上述操作才会起作用。

快速浏览mysql的“案例”

不过,你很可能会在这里找到答案:

实际上,您有一个SQL行,它有自己的内部switch语句。您只需告诉它当给定字段具有特定值时该怎么做。在上面的链接中,它的意思是

When `id` is 1, then set the value to 12. 
When `id` is 2, then set the value to 42. 
etc.
您唯一关心的可能是7000多行

但是,使用PHP,我将数据放在一个数组中,然后使用array_slice,一次获取200/300条记录,设置SQL行,然后执行。然后获取下一个200/300记录并重复,直到它到达PHP数组的末尾

编辑:
但是请记住,只有当您根据另一个字段(如密钥)更新一个字段时,上述操作才会起作用。

为什么需要存储排名?这是一个非规范化的形式,你真的需要它吗,或者你实现了那个步骤,因为它是预期需要的

例如,请参见此解决方案:

也许可以试试它的性能


此外,如果您看到他所做的示例,您可以在查询中使用变量。这还允许您将此update语句组合到单个查询中。循环中的查询是一个困难的查询,不幸的是,它甚至不会真正有效。

为什么需要存储排名?这是一个非规范化的形式,你真的需要它吗,或者你实现了那个步骤,因为它是预期需要的

例如,请参见此解决方案:

也许可以试试它的性能

此外,如果您看到他所做的示例,您可以在查询中使用变量。这还允许您将此update语句组合到单个查询中。循环中的查询是一个困难的查询,不幸的是,它甚至不会真正有效