简单的MySQL查询需要很长时间

时间:2009-04-18 17:37:55

标签: performance mysql

我们正在为一堆游戏运行统计网站,但是在日志超过100兆之后,事情开始变慢,所以我们需要优化我们的查询。

但是,我们发现我们认为是一个简单的查询,需要大约1.5秒:

SELECT handle,
(
    SELECT COUNT(*)
    FROM kills
    WHERE killer=p.handle
    AND k_team != c_team
    AND gid=p.gid
) AS kills
FROM players as p
WHERE  gid="3245"
AND team="axis"
ORDER BY kills DESC LIMIT 0, 10;

这会为其中一个团队生成结果列表。

表格杀戮和玩家分别包含36000和4000行。

为什么这个查询花了这么长时间才能进行优化?我们应该考虑加入吗?

祝你好运, 拉卡

5 个答案:

答案 0 :(得分:3)

通常,MySQL执行连接的速度比子选择快。要了解如何优化查询,建议您阅读EXPLAIN语法。

首先,确保您的kills表具有杀手和gid的复合索引,然后尝试此连接:

SELECT p.handle, COUNT(*) AS n_kills
FROM players p 
    JOIN kills k 
    ON p.handle = k.killer
        AND p.gid = k.gid
WHERE p.gid = 3245 
    AND p.team = "axis"
    AND k.k_team != k.c_team
GROUP BY p.handle
ORDER BY n_kills DESC LIMIT 0,10

查看这两个表的CREATE TABLE语句将有助于确定索引的任何问题。

答案 1 :(得分:1)

您是否尝试在killskiller列上添加索引?

编辑索引信息。 http://www.w3schools.com/Sql/sql_create_index.asp

答案 2 :(得分:0)

是的,你一定要考虑加入。从您发布的代码片段中很难判断,但是只要您可以在子查询中使用联接,这样做会很有用。

您可能还想考虑在数据库中的其他位置缓存kill count;特别是如果你使用的是InnoDB,COUNT()操作比简单地从数据库中选择一个[相对]最近的值需要更多的时间。您可以通过在相应的记录上增加kill count来轻松地在代码中实现这一点。或者类似的东西。

答案 3 :(得分:0)

尝试:

SELECT handle, count(*) as kills
FROM players as p
JOIN Kills as k ON k.gid = p.gid
WHERE  gid="3245"
AND team="axis"
ORDER BY kills DESC LIMIT 0, 10;

答案 4 :(得分:-1)

根据我的经验,限制中的偏移(LIMIT 0,10)是性能杀手。 如果您不限制并循环通过资源仅提取前十个记录行, 那么它将大大加快查询。 为什么?您不会获取完整资源,只需将资源指针移动到资源的末尾即可。 只有前十行受到影响,其他行被丢弃。资源有多大并不重要。就试一试吧。你会看到!

即。用PHP

$res=mysql_query("SELECT handle,
(
    SELECT COUNT(*)
    FROM kills
    WHERE killer=p.handle
    AND k_team != c_team
    AND gid=p.gid
) AS kills
FROM players as p
WHERE  gid="3245"
AND team="axis"
ORDER BY kills DESC;");

$i=0;
$results = array();
while($row=mysql_fetch_array($res)){
if($i<10){
  $results[] = $row;
}
$i++;
}

只有LINUX!

WINDOWS:

$i=0;
$results = array();
while($row=mysql_fetch_array($res)){
    if($i<10) {      
      $results[] = $row;
    } else {        
        mysql_close($db);
        break;
    }
     $i++;

}

假设indeces设置得很好。