Php 使用内部查询优化查询

Php 使用内部查询优化查询,php,mysql,sql,Php,Mysql,Sql,我正在开发一个应用程序,使用PHP可视化MySQL数据库中的数据。这是关于战场4中谁杀谁的日志。我想按降序列出使用特定武器的死亡人数,再细分为一个列表,显示此人的死亡人数,也按降序排列 数据库结构: 我的PHP代码将其可视化到选项卡上: <?php $con = mysql_connect("localhost", "bf4", "bf4") or die(mysql_error()); mysql_select_db("bf4") or die(mysql_error()); $qu

我正在开发一个应用程序,使用PHP可视化MySQL数据库中的数据。这是关于战场4中谁杀谁的日志。我想按降序列出使用特定武器的死亡人数,再细分为一个列表,显示此人的死亡人数,也按降序排列

数据库结构:

我的PHP代码将其可视化到选项卡上:

<?php
$con = mysql_connect("localhost", "bf4", "bf4") or die(mysql_error());
mysql_select_db("bf4") or die(mysql_error());

$query = mysql_query("SELECT p.playerId AS pid, p.playerName AS name,
    COUNT(`playerkills`.`id`) AS amount FROM `playerkills`
    JOIN players p ON playerkills.playerId = p.playerId
    WHERE weaponId = 9 GROUP BY playerkills.playerId ORDER BY amount DESC;")
    or die(mysql_error());

$i = 0;
$lastamount = -1;
$offset = 0;
while ($result = mysql_fetch_object($query)) {
    if ($lastamount != $result->amount) {
        $i += 1 + $offset;
        $offset = 0;
    } else {
        $offset++;
    }
    echo "<tr><td>".$i."</td><td>".$result->name."</td><td>".$result->amount."</td></tr>";
    echo "<tr><th></th><th>Target</th><th>Kills</th></tr>";

    $query_inner = mysql_query("SELECT p.playerName AS name,
        COUNT(`playerkills`.`id`) AS amount FROM `playerkills`
        JOIN players p ON playerkills.targetId = p.playerId 
        HERE weaponId = 9 AND playerkills.playerId = '{$result->pid}'
        GROUP BY playerkills.targetId ORDER BY amount DESC;");

    while ($result_inner = mysql_fetch_object($query_inner)) {
        echo "<tr><td></td><td>".$result_inner->name."</td><td>".$result_inner->amount."</td></tr>";
    }
    $lastamount = $result->amount;
}
mysql_close($con) or die(mysql_error());
?>

在循环中查询数据库不好,这样会创建太多查询。使用不同分组的两个查询可以得到相同的结果。这两个查询中的每一个都应该将playerkills表与武器表和players表连接起来

通过按playerId对第一个查询进行分组,可以得到该玩家的总击杀数。然后,通过按playerId对第二个查询进行分组,targetId将为您提供每个目标玩家的击杀数

例如(未测试)

查询1-每个玩家的总结果

SELECT p.playerId AS pid, p.playerName AS player, COUNT(*) AS kills
FROM playerkills pk
JOIN players p ON p.playerId = pk.playerId
WHERE weaponId = 9 
GROUP BY p.playerId,p.playerName ORDER BY kills DESC;
查询2-目标的详细结果

SELECT p2.playerName AS target, COUNT(*) AS kills 
FROM playerkills pk
JOIN players p ON p.playerId = pk.playerId
JOIN players p2 ON p2.playerId = pk.targetId
WHERE weaponId = 9
GROUP BY p.playerId,p2.playerId,p2.playerName ORDER BY p.playerId, kills DESC;

第二个查询只能在用户请求详细信息时调用,如您所示,在这种情况下,您可以在
where
子句之后添加类似
和p.playerId=$pid
的内容。在这种情况下,p.playerId在<代码>顺序中不需要,因为您将只获得特定玩家的结果,并且只需对其进行迭代。

对此的确切答案将非常长

我建议您尝试使用“with ROLLUP”修饰符

WITHROLLUP肯定会优化sql端的作业,但在php端需要一些技巧。 您应该将结果放在一个JSON对象中,然后使用javascript intead(静态创建php端)管理html表

如果有太多的数据需要在javascript上管理结果,那么您应该改变方法

首先需要一个PHP页面为您的详细信息生成JSON(一个Web服务,称之为GetDetails.PHP?someParams)。然后,您的主页应该只执行外部查询,并在每一行上放置一个链接以对其进行检查。 展开它意味着调用一个AJAX脚本来查询GetDetails.php?并通过DOM在表中添加新行


希望这有帮助

你的问题到底是什么?如何优化此代码?那么你在@kingkero可能会更好。我认为我现在做的大量查询是错误的,如果可能的话,最好是在一个查询中提取所有内容。根据我的经验,在大多数情况下,两个查询比使用子查询更好(我总是对我的s**t进行基准测试)。MySQL中存在一个bug,即内部查询中没有使用索引。在这里,您可以找到关于它的文档@melc执行两个查询不会优化作业。两个查询聚合相同数量的行,只是结果大小不同。如果用户希望两个结果都比两个查询得到更好的优化,那么使用汇总进行单个分组可以同时获得两个结果,代价是一个。使用汇总进行分组是一个不错的选择(+1)。但是,两个查询允许延迟加载详细信息结果。这两种方法肯定会优化当前的解决方案。在这种情况下,如果将
与ROLLUP一起使用,则似乎不可能按
金额进行排序,我似乎无法通过使用
与ROLLUP一起使用来进行正确的查询,虽然我知道它应该是如何工作的。你能解释一下为什么在查询1中你有
按p.playerId分组,p.playerName
,按
p.playerId分组是否进一步优化了查询?至于其余的,我认为在这种情况下,延迟加载是最可接受的解决方案,因为我不想给服务器施加太大的压力。@skiwi p.playerId和pk.playerId都应该被索引,因为一个是主键,另一个是外键,所以使用p.playerId还是pk.playerId应该没有区别。p.playerName已由添加到组中,以便在选择中也使用它。我知道mysql并不真正困扰您,您可以在select中添加任何内容,但只添加参与GROUPBY的列是正确的,也是有意义的。至于延迟加载,我同意,最好只在请求结果时检索和服务器结果。