在测试我的简单邮件MySQL数据库时,我发现了一个奇怪的行为,并且很高兴知道为什么。
我的“邮件”表有两个主键:
idx : INT(Auto-Increment)
uid : VARCHAR(50)
以及其他一些哑列,例如createdTime,info等。
然后,我用200,000个伪数据填充了我的表,并通过一个简单的搜索查询进行了测试:
SELECT * FROM mail WHERE uid='RANDOMGENERATEDUID';
执行此查询大约需要0.235秒,从工作台的表格说明中,我发现该查询执行全表扫描并且不使用任何键。
我很好奇,如果我 force 对SELECT查询使用'idx'列会发生什么,所以,我测试了另一个查询,该查询将具有相同的结果:
SELECT * FROM mail
WHERE idx IN (SELECT idx FROM foodwagondb.mail WHERE uid='RANDOMGENERATEDUID');
但是令我惊讶的是,该查询的执行速度更快,执行时间仅为0.078秒!
在这里我的眼睛后面发生了什么?我很高兴知道为什么会这样!
答案 0 :(得分:0)
您应避免使用IN
子句,而应使用INNER JOIN
SELECT m1.* FROM mail m1
INNER JOIN foodwagondb.mail m2 ON m2.idx = m1.idx
WHERE idx m2.uid='RANDOMGENERATEDUID';
IN子句等效于OR条件,这意味着针对每个值重复执行相关查询。内部联接仅执行查询并匹配结果值。
无论如何,您都可以使用适当的uid到
复合索引来改善这两个查询create index my_index on mail (uid, idx)
答案 1 :(得分:0)
在第一个查询中,您基于varchar字段(uid)搜索每一行。 在第二个查询中,mysql根据索引字段(idx)预先过滤行,然后在该子集中搜索文本字符串。对于较小的表,您看不到差异,但是对于较大的表,它会降低性能。 @scaisEdge是正确的,INNER JOIN规则!