我正在开发一款虚拟游戏板风格的游戏,玩家可以在棋盘的某个区域获得积分。 (现在就把它放在我身上,因为我只是做这个爱好所以我可能会以最坏的方式做到这一点)
我有3张桌子。一个存储所有玩家信息(例如,id,屏幕名称)。第二个存储所有区域信息(例如,id,x,y),第三个存储每个玩家在每个区域中具有多少点(例如,id,playerid,areaid,points)。为了创建一个"排行榜"我循环遍历所有玩家,然后在该循环中我也循环遍历所有区域,然后最终在第二个循环中,我得到该区域的领导者,看看它是否与当前玩家匹配第一个循环,如果是这样我增加一个计数器,然后将其存储到一个数组中。 (参见下面的代码并附上一些评论)
我研究了MySQL缓存,但我无法访问许多服务器选项,并且希望尽可能多地保留结果,因此缓存可能不是正确的方法。
我的问题是我是否正确地做到了这一点。目前只有大约10名球员,大约。 500个地区。我发现下面的脚本大约需要5-8秒才能运行。可能会有数百万个区域,因此如此长时间的处理延迟可能是灾难性的(无论如何对于排行榜)。我是否采用正确的方式,和/或有更好的方法吗?
<?php
$leaders = array();
//Loop through all the players
$sql = "SELECT * FROM players";
$result = mysqli_query($con, $sql) or die(mysqli_error($con));
while ($row = mysqli_fetch_array($result)) {
//save player information into variables
$playerId = $row['id'];
$playerScreenName = $row['screenname'];
//Reset the area counter
$AreaCount = 0;
$leader = array();
//Loop through all areas
$sql2 = "SELECT * FROM areas";
$result2 = mysqli_query($con, $sql2) or die(mysqli_error($con));
while ($row2 = mysqli_fetch_array($result2)) {
$areaId = $row2['id'];
//Get the player with the most points in that area
$sql3 = "SELECT * FROM points WHERE areaid='$areaId' ORDER BY totalpoints DESC LIMIT 1";
$result3 = mysqli_query($con, $sql3) or die(mysqli_error($con));
while ($row3 = mysqli_fetch_array($result3)) {
$leaderOfArea = $row3['playerid'];
//See if the leader of the area is the same player we are looping through
if ($playerId == $leaderOfArea) {
//if it is, then increment the counter
$AreaCount++;
}
}
}
//Store the leader information into an array to be output later
$leader['screenname'] = $playerScreenName;
$leader['areacount'] = $AreaCount;
$leaders[] = $leader;
}
// sort leaders by score
usort($leaders, 'compare_areacount');
?>
答案 0 :(得分:0)
打开数据库连接会产生开销,当你在循环中执行它时,会加剧问题(然后当你在其中添加一个循环时,你会让它变得更糟)。而是使用Join或Subquery将其重组为一个查询。
答案 1 :(得分:0)
我认为这段代码可以提供帮助。您可能必须使用所需的适当列名更改sql查询。
<?php
$leaders = array();
//Loop through all the players
$sql = "SELECT * FROM players";
$result = mysqli_query($con, $sql) or die(mysqli_error($con));
$players = array();
while ($row = mysqli_fetch_array($result)) {
//save player information into variables
$players[$row['id']] = array($row['screenname'], 0);
// number 0 will be the count of how many times this player is the leader
}
$sql = "SELECT Area.id, Area.name, (SELECT Pts.playerid FROM `points`"
. " AS Pts WHERE Pts.areaid=Area.id ORDER BY totalpoints"
. " DESC LIMIT 1) AS `leader_id` FROM `areas` AS Area";
$result = mysqli_query($con, $sql) or die(mysqli_error($con));
$areas = array();
while ($row = mysqli_fetch_row($result)) {
$areas[$row[0]] = $row;
// $row[2] will contain leader_id
// index 1 corresponds to the second element in player values array
$players[$row[2]][1]++;
}
// now if you want to print:
foreach ($areas as $area_id => $area) {
echo "Area id: " . $area_id . ", name: " . $area[1] . ", leader_id: " . $area[2] . "<br /><br />";
}
foreach ($players as $player_id => $player) {
echo "Player id: " . $player_id . ", name: " . $player[0] . ", No of areas this player is a leader of: " . $player[1] . "<br /><br />";
}