简单的MySQL查询需要很长的时间
我们正在为一堆游戏运行一个统计站点,但是在日志已经超过100MB后,事情开始放缓,所以我们需要优化我们的查询。简单的MySQL查询需要很长的时间
然而,我们发现,我们认为是一个简单的查询,需要大约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行恭敬地。
为什么这个查询需要这么长时间,它如何优化?我们应该看看JOIN吗?
最好的问候, 拉卡
一般情况下,MySQL的执行比加入快子查询。要了解如何优化查询,我建议阅读EXPLAIN语法。
首先,确保你的杀敌表有杀手和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语句这两个表将帮助确定您的索引的任何问题。
你试过把一个指标上kills
表killer
列?
编辑有关索引的信息。 http://www.w3schools.com/Sql/sql_create_index.asp
对于CREATE INDEX你的意思是?什么类型的索引?你能更具体吗? – 2009-04-18 17:45:45
是的,你应该看看连接。很难从你发布的代码片段中知道,但是只要你可以在子查询上使用连接,那么这样做会有好处。
您可能还想考虑缓存kill count在数据库的其他地方;特别是如果你使用的是InnoDB,COUNT()操作比从数据库中选择[相对]最近的值需要更多的时间。您可以通过在适当的记录上增加kill count或类似的东西,在代码中轻松实现这一点。
大多数数据库会在运行之前尝试优化查询。这适用于有子查询的查询。 – Marius 2009-04-18 17:46:12
你是说根本不需要优化你的查询吗? – Calvin 2009-04-18 18:02:51
不应该依靠他的数据库引擎来重构不适当的代码;优化是必要的保守,数据库不能总是确定你的意图,优化有助于填补空白,而不是重写你的整个程序的理智和表现;这是你的工作 – jeffcook2150 2009-04-18 18:06:29
尝试:
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;
根据我的经验,限制(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被设置好的良好。
表'杀死'是否有GID以外的玩家FK?看起来你缺少'team ='axis'join,除非gid足够。 – 2009-04-18 18:53:23