【问题标题】:Really big SELECT query非常大的 SELECT 查询
【发布时间】:2012-06-20 15:59:30
【问题描述】:

我想问有没有更快的方法来做这个查询?实际上它需要大约 100 秒才能完成。我在一个表中有大约 10 000 000 (1 GB) 行。这是统计生成脚本。

这是查询:

  $results=mysql_query("SELECT * FROM hawkeye WHERE player_id='".$playerID."'") or die("MYSQL ERROR: ".mysql_error());

然后是php代码:

  $row = mysql_fetch_array($results)
  if($row["action"] == 4){$commandcount++;}
  else if($row["action"] == 3){$chatcount++;}
  else if($row["action"] == 1){$placedcount++;}
  else if($row["action"] == 0){$breakcount++;}
  else if($row["action"] == 5){$joincount++;}
  else if($row["action"] == 6){$quitcount++;}
  else if($row["action"] == 7){$qteleportcount++;}
  else if($row["action"] == 12){$pvpdeathcount++;}
  else if($row["action"] == 21){$mobkillcount++;}
  else if($row["action"] == 22){$otherdeathcount++;}
  else {}

感谢您的回答!

【问题讨论】:

  • 您真的需要一次选择所有 10 000 000 行吗?为什么?
  • 立即从您的查询中删除 *。定位你想要的列,即使你想要它们,不使用*会更快。
  • 让我猜猜:player_id 字段上没有索引,对吧?
  • @Pekka 因为它是用于统计的。
  • 可能可以直接在 mySQL 中进行这些统计。这样可以节省大量流量

标签: php mysql sql optimization


【解决方案1】:

使用 MYSQL 为您计算。它比 PHP 更快:

SELECT COUNT(*) AS action_count
     , action
FROM hawkeye 
WHERE player_id='".$playerID."'"
GROUP BY action

while ($row = mysql_fetch_assoc($result))
{
    echo $row['action'] . ': ' . $row['action_count'] . "<br>" . PHP_EOL;
}

【讨论】:

  • 还要确保 player_id 已编入索引
  • @Mato Kormuth:1) John Conde 是正确的——如果你可以在 SQL 中做某事,那么你应该在 SQL 中做。它效率更高。 2)raina77ow 也是正确的。您应该在 hawkeye 上有一个 player_id 的索引。如果你还没有,那么缺少索引很可能是整个问题。
  • 有没有被索引也没关系,还是要读10M的记录才能得到一个COUNT,如果只是一个人的单次请求就好了。它不会表现良好。
  • @CraigTrombly:当然索引很重要:您只想查看符合条件player_id=? 的记录。更重要的是,不要像这样 ('".$playerID."') 将值直接放在查询字符串中:使用准备好的语句来防止 SQL 注入(或者至少使用 mysql_real_escape_string)。
  • 谢谢,现在大约需要 2 秒!
【解决方案2】:

怎么样

SELECT action, count(*) FROM hawkeye WHERE player_id='$playerID' GROUP BY action

所以每个动作类型只会循环一次,而不是每个动作

【讨论】:

  • 原始代码中只提取了一行。但总的来说,您的回答非常好,+1。 )
【解决方案3】:

您似乎正在尝试进行一些计算。尝试研究聚合或使用像 infobright 这样的分析数据库,它将聚合存储在内存中。避免执行 SELECT * 并执行实际的 SELECT column1, column2。大多数情况下,虽然读到了像 SUM、COUNT Group BY 和 Order By 这样的聚合。

【讨论】:

    【解决方案4】:

    为 hawkeye 表添加一个索引,该表按 player_id 编制索引,并遵循 John Conde 的建议。

    【讨论】:

      【解决方案5】:
      $results=mysql_query("SELECT action, count(*) as `cnt` FROM hawkeye WHERE player_id='".$playerID."' GROUP BY action") or die("MYSQL ERROR: ".mysql_error());
      
      while ($row = mysql_fetch_array($results)) {
        if($row["action"] == 4){$commandcount=$row["cnt"];}
        else if($row["action"] == 3){$chatcount=$row["cnt"];}
        else if($row["action"] == 1){$placedcount=$row["cnt"];}
        else if($row["action"] == 0){$breakcount=$row["cnt"];}
        else if($row["action"] == 5){$joincount=$row["cnt"];}
        else if($row["action"] == 6){$quitcount=$row["cnt"];}
        else if($row["action"] == 7){$qteleportcount=$row["cnt"];}
        else if($row["action"] == 12){$pvpdeathcount=$row["cnt"];}
        else if($row["action"] == 21){$mobkillcount=$row["cnt"];}
        else if($row["action"] == 22){$otherdeathcount=$row["cnt"];}
        else {}
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        相关资源
        最近更新 更多