MySQL In不能用內連線改寫

壹頁書發表於2015-05-12
原來面試的時候,是作為面試題背的..
什麼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) 參考:
http://www.cnblogs.com/xiaotengyi/p/3908347.html



主銀你當我們傻啊

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1649928/,如需轉載,請註明出處,否則將追究法律責任。

相關文章