为什么这个查询对MySQL这么慢?

时间:2013-11-14 07:10:59

标签: mysql sql query-optimization

昨天我发现在服务器上运行的查询速度很慢(这个查询花费超过1分钟)。看起来像这样:

select a.* from a 
left join b on a.hotel_id=b.hotel_id and a.hotel_type=b.hotel_type
where b.hotel_id is null

表a中有40000多行,表b中有10000多行。已经在表b中的列hotel_id和hotel_type上创建了一个唯一键,如UNIQUE KEY idx_hotel_idhotel_id,{ {1}})。所以我使用了explain关键字检查了这个sql的查询计划,得到了如下结果:

hotel_type

根据MySQL的参考手册,当连接使用索引的所有部分并且索引是PRIMARY KEY或UNIQUE NOT NULL索引时,连接类型将是“eq_ref”。参见查询的第二行计划,列类型的值是“索引”。但我确实在hotel_id和hotel_type上有唯一索引,并且连接使用了两列。连接类型“ef_ref”比连接类型“ref”更有效并且“ref”比“range”更有效。“index”是最后的连接类型wo wanna hava除了“ALL”。这是我很困惑的,我想知道为什么这里的连接类型是“索引”。我希望我能清楚地描述我的问题,我期待着你们的回答,谢谢!

2 个答案:

答案 0 :(得分:1)

Null检查在哪里可能很慢,所以也许就是这样。

select * from a 
where not exists ( select 1 from b where a.hotel_id=b.hotel_id and a.hotel_type=b.hotel_type )

另外:你回来了多少条记录?如果你要返回所有36804条记录,这也会减慢速度。

答案 1 :(得分:0)

感谢上面的所有人!我找到了自己解决问题的方法。列hotel_id和hotel_type没有相同的字符集。在我将它们都设为“utf8”之后,我的查询返回的结果大约小于10毫秒。关于MySQL的左连接和索引有一篇很好的文章,我强烈推荐给你们。这是网站:http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/