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)
);
但是此時如果用內串連改寫..
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);
可以看到,兩種方式的結果並不相同..
從邏輯上看,In後面的子查詢經過了去重.
原來是通過Exists實現的.MySQL 5.6之後,採用了Semi Join最佳化.
半串連(Semi Join) 參考:
本文永久更新連結地址: