Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这些查询会破坏MySQL的性能?我怎样才能修好它们?_Mysql_Performance_Cpu - Fatal编程技术网

为什么这些查询会破坏MySQL的性能?我怎样才能修好它们?

为什么这些查询会破坏MySQL的性能?我怎样才能修好它们?,mysql,performance,cpu,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

我创建了一个缓慢的查询日志,以找出当站点负载不足时,是什么导致我的服务器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
我知道考虑到检查/发送的行数比率存在严重问题,但我不知道该怎么办。在一周的时间里,我已经根据调谐器调整了我的.cnf。游戏表大约有12万行,存款表大约有25万行


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

如果您不向我们展示
游戏
存款
,我们所知不多,但是如果您在
游戏中没有
游戏
的索引(或者更好的是,在
game\u-over
id-DESC
上按该顺序建立复合索引),在
存款
中建立
game\u-id
索引(或者更好的是,在
game\u-id
user\u-id
上建立复合索引),那么这就是问题的开始。

而不是使用

Select * from.....
我建议使用表中所需的特定字段:

Select id,name,......

您需要索引,但也需要正确表达查询

对于此查询:

SELECT *
FROM games
WHERE game_over = 0
ORDER BY id DESC
LIMIT 100;
SELECT *
FROM deposits
WHERE game_id = '109067' AND user_id = '19153';
最佳索引在
games(game_over,id desc)
上。这既满足
where
子句,也满足
order by
。这很好

对于此查询:

SELECT *
FROM games
WHERE game_over = 0
ORDER BY id DESC
LIMIT 100;
SELECT *
FROM deposits
WHERE game_id = '109067' AND user_id = '19153';
最佳索引位于存款(游戏id、用户id)
(列可以是任意顺序)。但是请注意,如果id字段是数字字段,请删除引号:

SELECT *
FROM deposits
WHERE game_id = 109067 AND user_id = 19153;
在比较中使用错误的类型可能会导致索引未被使用。(我认为您的特定示例是可以的,但这仍然是一个坏习惯。)


显式列出列不太可能提高性能。但是,这是一个好主意,因为如果表发生变化,它会使代码更加健壮。

第一个问题是,为什么您要尝试将所有内容都拉回来?您的表有多少列,您能提供一些示例数据在查询和MySQL之前添加
解释
我会给你一份很好的报告,告诉你它打算如何把数据拿出来。我猜你需要一个游戏ID和用户ID的索引。这两个查询都很快,但如果它们每分钟被调用200次,你需要某种缓存。嗨,谢谢你的回复。我应该为这些表使用“键”索引吗?我的ID列是“主”列两个有问题的表的索引。我不明白复合索引是什么?编辑:向引用用户ID的所有字段添加键使CPU使用率下降了很多!谢谢。但它仍然徘徊在100-200%左右。@SteveP:当然。是的,一个“键”索引。复合索引是一个包含多个列的索引;一个查询只能查看一个索引,因此,如果您的查询搜索多个列,则只有当索引包含其搜索的所有列时,它才能获得完整的索引性能。有关更多信息,请阅读此处:@SteveP-@chaos说的是
索引(游戏id,用户id)
,而不是
索引(游戏id)
索引(用户id)
。在第二种情况下,复合(复合)索引更好。