我正在使用MySQL 5.5.25服务器和用于数据库的InnoDB。
由于mysqld进程大约一分钟的时间,服务器的CPU经常以100%的速度工作。使用SHOW PROCESSLIST:
Command | Time | State | Info
Query | 100 | Sending data | SELECT a.prefix, a...
Query | 107 | Sending data | SELECT a.prefix, a...
Query | 50 | Sending data | SELECT a.prefix, a...
有问题的查询是:
SELECT a.prefix, a.test_id, a.method_id, b.test_id
FROM a
LEFT JOIN b ON b.test_id = a.test_id
AND user_id = ?
AND year = ?
所有这些列都是INDEXED,因此这不是问题。另外,当我在phpMyAdmin中运行查询(具有足够的LIMIT)时,需要0.05秒才能完成。同样,令人沮丧的是,我发现自己无法重现此问题,即使同时执行两次此查询并向其发送垃圾邮件也只会使我的峰值CPU利用率提高到40%。
使用EXPLAIN前缀查询会导致:
Id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | a | ALL | NULL | NULL | NULL | NULL | 1169 |
1 | SIMPLE | b | ref | user_id,year,test_id | test_id | 4 | db.a.test_id | 58 |
除非我看不到眼前的真相,否则我正在寻找方法来发现如何调试此类问题。我已经记录了所有查询及其执行时间和值等信息。但是由于无法重现它,所以我陷入了困境。我应该怎么做才能弄清楚这个问题是什么?
哇,感谢Masood Alam的评论,我找到并解决了这个问题。
使用SHOW ENGINE INNODB STATUS
事实证明对调试非常有帮助。
事实证明,对于某些值,user_id
数据库对事物的处理方式有所不同,因此其行为不可预测,并且无法重现该问题。通过status命令,我能够复制并粘贴当前正在运行的确切查询。
这是该EXPLAIN
特定值对user_id
以下结果的结果:
Id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | a | ALL | NULL | NULL | NULL | NULL | 841 |
1 | SIMPLE | b | index_merge | user_id,year,test_id | user_id,year | 4,4 | NULL | 13 | Using intersect(user_id,year); Using where
现在的后续问题是如何解释这种行为。但是,为我解决问题只是将查询更改为:
SELECT a.prefix, a.test_id, a.method_id, b.test_id
FROM a
LEFT JOIN b ON b.test_id = a.test_id
WHERE
b.id IS NULL
OR user_id = ?
AND year = ?
其中EXPLAIN
导致:
Id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | a | ALL | NULL | NULL | NULL | NULL | 671 |
1 | SIMPLE | b | ref | test_id | test_id | 4 | db.a.test_id | 49 | Using where
现在我知道,在给定不同输入值的情况下,InnoDB可以有不同的方法来执行查询。为什么?我还是不知道
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句