我正在运行一个简单的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万条记录。
答案 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)