哇,感谢Masood Alam的评论,我发现并解决了这个问题.
使用SHOW ENGINE INNODB STATUS在调试方面非常有用.
事实证明,对于user_id的某些值,数据库以不同的方式处理事物,因此其不可预测的行为并且无法重现问题.通过status命令,我能够复制并粘贴当前正在运行的确切查询.
这是针对user_id的特定值的EXPLAIN的结果:
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可以有不同的方法来执行给定不同输入值的查询.为什么?我还是不知道.