MySQL求和查询需要花费大量时间才能完成。寻找瓶颈

时间:2013-07-30 09:12:41

标签: mysql database performance

我正在运行一个简单的MySQL查询来查找用户花在游戏上的总时间:

SELECT userId, SUM(time) AS totalGameTime
                    FROM game_attempts
                    WHERE userId = 19599

EXPLAIN显示以下内容:

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra
1  SIMPLE  game_attempts  ref  userId_gameId  userId_gameId  4  const  26880  

PROFILER显示,大部分时间花在“发送数据”上:

Sending data    1.786524

为什么这么简单的查询需要花费很多时间才能完成?在哪里寻找瓶颈?

更新。时间是INT(11)字段,不涉及任何转化。

UPDATE。可能的解决方案是引入(userId,time)索引,它通过将部分数据移动到索引树来解决问题。但它并没有解决为什么总结30000个整数需要这么长时间的更大问题。

这个问题没有一个简单的答案。指数是正确的,不涉及耗时的转换。这只是关于DB eninge tuning - 为什么找到那些30000条记录并检索数据需要花费很多时间?

重要的是说使用InnoDB引擎的表并且拥有大约200万条记录。

6 个答案:

答案 0 :(得分:1)

尝试为userId创建索引,这样可以解决您的问题:

   ALTER TABLE game_attempts ADD INDEX (userId);

答案 1 :(得分:1)

它建议您将大量行返回给客户端。 你能加

吗?
GROUP BY userId

确保只返回一行?

答案 2 :(得分:0)

在userId上创建一个索引。这限制了对userId失败的记录的访问。

答案 3 :(得分:0)

在几乎任何其他DBMS中,您的语句将被视为无效SQL,因为查询的select部分包含聚合函数以及不属于GROUP BY子句的字段 - 实际上,您没有GROUP BY子句。

Oracle,例如会告诉你:

  

ORA-00937:不是单组组功能

你会在MSSQL中得到类似的东西。 我猜这里MySQL所做的是比常规更频繁地计算SUM方式。

以下查询将更符合SQL标准,并且会更快:

SELECT userId, SUM(time) AS totalGameTime
  FROM game_attempts
 WHERE userId = 19599
GROUP BY userId;

答案 4 :(得分:0)

“时间”栏上的精确度过高? 怎么样总结

SEC_TO_TIME(SUM(TIME_TO_SEC(time)))

代替?

答案 5 :(得分:0)

好的,我注意到这是一个答案,所以你不能再犯这个错误

关闭MySQL 5.0.23,您可以设置

ONLY_FULL_GROUP_BY by SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY ';

正确配置服务器

mysql> SELECT name, MAX(age) FROM t;
ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)
with no GROUP columns is illegal if there is no GROUP BY clause

来源(http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_only_full_group_by

相关问题