外表:tablea
內錶:tableb
in:select * from tablea where tablea.id in ( select a_id from tableb )
exists:select * from tablea where exists ( select * from tableb where tableb.a_id = tablea.id )
in的執行原理,是把外表和內錶做hash連線,主要用到外表索引
exists的執行原理,是對外表做loop迴圈,主要用到內錶索引
in 查詢
第1條查詢其實就相當於or語句,假設b表有a_id分別為id1,id2 … idn這n條記錄,那麼上面語句可以等價轉化成:
select
*from tablea where tablea.id = id1 or tablea.id = id2 or..
.or tablea.id = idn;
主要是用到了a表的索引,b表的大小對查詢效率影響不大
exists 查詢
第2條查詢,可以理解為類似下列流程
function
getexists()
}return resultset
}
主要是用到了b表的索引,a表大小對查詢效率影響不大
select
*from tablea where tablea.id notin(
select a_id from tableb )
select
*from tablea where
notexists
(select
*from tableb where tableb.a_id = tablea.id )
not in 查詢
類似,第1條查詢相當於and語句,假設b表有a_id分別為id1,id2 … idn這n條記錄,那麼上面語句可以等價轉化成:
select
*from tablea where tablea.id != id1 and tablea.id != id2 and..
.and tablea.id != idn
not in是個範圍查詢,由於! =不能使用任何索引,故a表的每條記錄,都要在b表裡遍歷一次,檢視b表裡是否存在這條記錄,而not exists還是和上面一樣,用了b的索引,所以無論什麼情況,not exists都比not in效率高
總結:如果查詢的兩個表大小相當,那麼用in和exists效率差別不大。
如果兩個表中乙個較小,乙個較大,則子查詢表大的用exists,子查詢錶小的用in。
例如:有表a (小表)和表b(大表)
1:select * from a where cc in (select cc from b)
效率低,用到了a表上cc列的索引;
select * from a where exists(select cc from b where cc=a.cc)
效率高,用到了b表上cc列的索引。
2:select * from b where cc in (select cc from a)
效率高,用到了b表上cc列的索引;
select * from b where exists(select cc from a where cc=b.cc)
效率低,用到了a表上cc列的索引。
not in 和not exists如果查詢語句使用了not in 那麼內外表都進行全表掃瞄,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。所以無論那個表大,用not exists都比not in要快。
mysql in 和exists查詢效率總結
看到網上好多的文章,關於in 和exists,我自己專門去校驗了一下,自己通過儲存過程,迴圈增加了10萬條資料,建立表 drop table if exists tb test create table tb test id int primary key auto increment not nu...
MYSQL IN 與 EXISTS 的優化示例介紹
當b表的資料集必須小於a表的資料集時,用in優於exists,當a表的資料集系小於b表的資料集時,用exists優於in 優化原則 小表驅動大表,即小的資料集驅動大的資料集。原理 rbo select from a where id in select id from b 等價於 for selec...
MYSQL IN 與 EXISTS 的優化示例介紹
優化原則 小表驅動大表,即小的資料集驅動大的資料集。原理 rbo 程式設計客棧select from a where id in select id from b 等價於 for select id from b for select from a where a.id b.id 當b表的資料集必須...