执行此操作的最快方法是什么?PHP / SQL / Sort

时间:2017-05-25 20:07:58

标签: php mysql sorting time

所以我的数据库结构是:

steamid | mapname | name | teleports | runtime | runetimepro | teleports_pro

enter image description here

所以我需要做的是每个地图我需要弄清楚玩家在运行该地图的人中的等级。玩家可以使用protime(runtimepro)或正常时间(运行时)运行地图。因此,如果一个游戏同时具有正常时间和正常时间,那么我必须知道他的时间和正常时间的等级(它们彼此独立)。

我目前的做法是让一个foreach循环遍历每个mapname,并将播放器的steamid,mapname和run类型发送给一个函数,然后查询数据库。代码如下:

function getKZTimeRank($steamID, $map, $type, $dbkz){
    if($type == "Pro"){
        $stmt = "SELECT * From playertimes WHERE mapname = :mapname AND runtimepro <> -1 ORDER BY runtimepro DESC";
        $query = $dbkz->prepare($stmt);
        $query->bindValue(":mapname", $map);
        $query->execute();
        $items = $query->fetchAll(PDO::FETCH_ASSOC);
        $count = 1;
        foreach($items as $map){
            if ($map['steamid'] == $steamID){
                return $count;
            }else{
                $count++;
            }
        }
    }elseif($type == "TP"){
        $stmt = "SELECT * From playertimes WHERE mapname = :mapname AND runtime <> -1 ORDER BY runtime DESC";
        $query = $dbkz->prepare($stmt);
        $query->bindValue(":mapname", $map);
        $query->execute();
        $items = $query->fetchAll(PDO::FETCH_ASSOC);
        $count = 1;
        foreach($items as $map){
            if ($map['steamid'] == $steamID){
                return $count;
            }else{
                $count++;
            }
        }
    }
}

代码只抓取我们要查找的地图以及该地图的所有时间(由$type确定的专业或正常)并按降序提取。通过地图排序的玩家,它将使用计数器搜索steamid并返回它找到玩家的位置。这对于小型数据集的工作和工作相当快,但我试图按地图和那里列出玩家的时间有几百张地图和几千名玩家。该脚本需要一些时间来运行,因为它需要为播放器运行的每个地图运行查询。有一个外部循环可以获取玩家运行的所有地图,并获得地图的时间,然后该函数可以找到该时间在其他时间的位置。因此,对于我的个人资料,我已经完成了190个地图,因此对于每个地图,它必须至少运行此功能1次。如果我既有专业时间也有正常时间,有些地图要求它运行两次。因此,最少我在最多380(加1)查询时执行190次查询(加上1次外部查询)。这个脚本对我来说只需要6.5秒左右,但对于其他玩家来说,需要12到15秒。有一个更好的方法吗?我已经研究过array_multisort(),但我不确定这是否有利于这个项目。你能帮忙的话,我会很高兴。我是以最好的方式之一做的吗?如果事情不清楚,我可以尝试纠正任何困惑。

1 个答案:

答案 0 :(得分:0)

也许你能尝试的一件事是:

获取所有玩家的信息:

SELECT * FROM playertimes WHERE steamid = :steamid and mapname = :mapname

然后你可以计算玩家时间之前的每一次:

SELECT COUNT(*) as aggregate From playertimes WHERE mapname = :mapname AND runtimepro <> -1 AND runtimepro < :runtimepro

然后你有一个玩家的等级:

$item = $query->fetch();
$rank = $item->aggregate;

对于普通运行时

也可以这样做

我认为它会起作用,但我不知道它是否会更快