我创建了一个慢速查询日志,以确定当网站负载时导致我的服务器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行。
最后我知道我的服务器无法扩展,所以我如何修复这些查询以及其他人在负载下运行良好?
答案 0 :(得分:2)
如果您没有向我们展示games
和deposits
的架构,但是如果您在game_over
中没有games
的索引,我们就不会知道多少1}}(甚至更好,game_over
上的复合索引和id DESC
的顺序),以及game_id
中deposits
的索引(甚至更好,一个化合物) game_id
和user_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;
在比较中使用错误的类型可能导致索引未被使用。 (我认为你的具体例子还可以,但它仍然是一个坏习惯。)
明确列出列不太可能提高性能。但是,这是一个好主意,因为如果表更改,它会使代码更加健壮。