MySQL In不能用内连接改写

原来面试的时候,是作为面试题背的..
什么MySQL In 使用Exists方式,很慢...
面试官问怎么办..回答用内连接改写..
然后面试官露出满意笑容..

一直以来都是这个剧本..
直到昨天我才发现..这个剧本原来是错的.

实验数据
create table song(
 songid int
 );
 insert into song values(1),(2),(3);

 create table song_category_relation(
 Category varchar(10),
 songid int
 );
 insert into song_category_relation values
 ('华语',1),
 ('华语',2),
 ('华语',3),
 ('热门',3);

 song是歌曲表
song_category_relation是歌曲和分类的映射关系表.
一个歌曲可能有多个分类.

需求.
已知一个歌曲的ID,找到这个歌曲所属的所有分类,然后再找到所有分类下的所有歌曲.

使用In
 select * from song where songid in (
 select songid from song_category_relation where Category in
 (select Category from song_category_relation where songid=3)
 );

MySQL In不能用内连接改写

但是此时如果用内连接改写..
select * from song inner join  (
 select songid from song_category_relation where Category in
 (select Category from song_category_relation where songid=3)
 ) a on (a.songid=song.songid);

MySQL In不能用内连接改写

可以看到,两种方式的结果并不相同..
从逻辑上看,In后面的子查询经过了去重.
原来是通过Exists实现的.MySQL 5.6之后,采用了Semi Join优化.

相关推荐