为什么这些查询会破坏MySQL性能?我该如何解决这些问题?

时间:2015-11-04 22:06:46

标签: mysql performance cpu

我创建了一个慢速查询日志,以确定当网站负载时导致我的服务器CPU使用率出现峰值的原因。我发现了这些问题。

SELECT * FROM games WHERE game_over = 0 ORDER BY id DESC LIMIT 100;
# User@Host: root[root] @ localhost [127.0.0.1]
# Thread_id: 2545188  Schema: qe QC_hit: No
# Query_time: 0.162958  Lock_time: 0.000030  Rows_sent: 1  Rows_examined: 218089

其中许多都在弹出,因为我们有一个通过运行此查询来刷新的大厅系统。这可以很容易地每分钟运行200次以上,我觉得这会导致您在其他帖子中看到的疯狂CPU使用率。 (负载时为400%+,8芯)。这是另一个经常在日志中弹出的例子。

SELECT * FROM deposits WHERE game_id = '109067' AND user_id = '19153';
# User@Host: root[root] @ localhost [127.0.0.1]
# Thread_id: 2545260  Schema: qe QC_hit: No
# Query_time: 0.261047  Lock_time: 0.000038  Rows_sent: 1  Rows_examined:   218091

我知道考虑行检查/发送比例存在严重问题,但我对此怎么办感到难过。我已经根据调谐器在几周的时间内调整了my.cnf。游戏桌有大约120k行,存款表大约有250k行。

最后我知道我的服务器无法扩展,所以我如何修复这些查询以及其他人在负载下运行良好?

3 个答案:

答案 0 :(得分:2)

如果您没有向我们展示gamesdeposits的架构,但是如果您在game_over中没有games的索引,我们就不会知道多少1}}(甚至更好,game_over上的复合索引和id DESC的顺序),以及game_iddeposits的索引(甚至更好,一个化合物) game_iduser_id上的索引,那就是问题的开始。

答案 1 :(得分:0)

而不是使用

Select * from.....

我建议使用表中所需的特定字段

Select id,name,......

答案 2 :(得分:0)

您需要索引,但您还需要正确地表达您的查询。

对于此查询:

SELECT *
FROM games
WHERE game_over = 0
ORDER BY id DESC
LIMIT 100;

最佳索引位于games(game_over, id desc)。这满足where子句和order by。没关系。

对于此查询:

SELECT *
FROM deposits
WHERE game_id = '109067' AND user_id = '19153';

最佳索引位于deposits(game_id, user_id)上(列可以按任意顺序排列)。但请注意。如果id字段是数字,则删除引号:

SELECT *
FROM deposits
WHERE game_id = 109067 AND user_id = 19153;

在比较中使用错误的类型可能导致索引未被使用。 (我认为你的具体例子还可以,但它仍然是一个坏习惯。)

明确列出列不太可能提高性能。但是,这是一个好主意,因为如果表更改,它会使代码更加健壮。