所以我的数据库结构是:
steamid | mapname | name | teleports | runtime | runetimepro | teleports_pro
所以我需要做的是为每张地图找出一个跑过该地图的球员的排名。玩家可以使用protime(runtimepro)或正常时间(runtime)来运行地图。因此,如果一部戏既有正常时间又有正常时间,那么我就必须知道他在正常时间和正常时间上的排名(他们彼此独立)。
我当前执行此操作的方法是有一个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
确定的pro或法线),并以降序拉取。对于那些按地图排序的玩家,它将使用计数器搜索半成品,并返回找到玩家的位置。这对于少量数据非常有效,但我尝试按地图列出玩家的时间有几百张地图和几千名玩家。该脚本需要花费一些时间来运行,因为它需要为播放器运行的每个地图运行一个查询。有一个外部循环可以获取玩家已运行的所有地图,并获取地图的时间,然后该函数可以找到该时间在其他时间中的放置位置。例如,对于我的个人资料,我已经完成了190张地图,因此对于每张地图,它必须运行此功能至少1次。如果我既有常规时间,又有一些地图要求将其运行两次。因此,我最少执行190个查询(加1个外部查询),最多执行380个(加1)查询。这个脚本对我来说只需要6.5秒左右,而对其他玩家来说则需要12到15秒。有一个更好的方法吗?我已经研究了array_multisort(),但是不确定是否对这个项目有利。你能帮忙的话,我会很高兴。我是用最好的方法之一做吗?如果有不清楚的地方,我可以尝试纠正任何混乱。 最佳答案
也许您可以尝试的一件事是这样的:
获取一个玩家的所有信息:
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;
正常运行时也可以这样做
我认为它会起作用,但我不知道它会不会更快
关于php - 什么是最快的方法来执行此PHP/SQL/Sort,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44189006/