5

昨天我发现服务器上运行的查询很慢(这个查询花费超过 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_id( hotel_id, hotel_type)。所以我使用了 explain 关键字来检查查询计划这个sql,我得到如下结果:

                type            key                             rows
1   SIMPLE  a   ALL     NULL    NULL            NULL    NULL    36804   
1   SIMPLE  b   index   NULL    idx_hotel_id    185     NULL    8353    Using where; Using index; Not exists

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

4

2 回答 2

1

Where Is 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 记录,这也可能会减慢速度。

于 2013-11-14T07:34:45.387 回答
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/

于 2013-11-17T16:10:15.093 回答