mysql in型子查詢陷阱

2022-08-23 05:39:08 字數 795 閱讀 6973

現在有兩個表,table1和table2,table1有1千萬資料(id 主鍵索引),table2有三條資料(uid欄位 3,5,7);

select * from table1 where id in ( select uid from table2 );

眨眼一看感覺這條語句應該很快;可能你會一廂情願的以為 先執行括號裡面的語句,然後在執行外層的select;外層的select用上了 id主鍵速度應該飛起來才對;

實際上這條語句執行非常慢,我這裡測試20s;

通過  explain 分析,這條語句沒有用上索引,而是全表掃瞄;原因在**?

實際上 mysql 內部不是照著我們的想法來執行的,他是從外層執行起走,每掃一行就把id拿來和內層查詢比較,所以外層是全表掃瞄;

把這條語句改成:

select * from table1 where id in ( 3,5,7 );  【補充一點,在mysql內部  in 會被自動轉化為  exists】

執行時間程式設計毫秒級了,通過explain 檢視 使用了range 掃瞄,可以看出mysql內部操作原理;

然後我們再來看一下有沒有解決方案:

select table1.* from table1 inner join table2 on table1.id=table2.uid;

查詢時間也是毫秒級的;

這次通過 explain 發現  ,mysql先執行了 select uid from table2,然後執行select table1 並且使用了 eq_ref 一對一索引;

mysql in 後子查詢優化

線上資料發現一條資料大量等待的現象,通過explain發現這個sql寫法存在問題,這裡簡單記錄一下.業務場景是這樣 存在購物車和費用兩張表,購物車資料是購買商品時生成,用於記錄購買商品資料,同時購買的商品也會生成費用表,用於統計商品總的支出情況 相當於訂單 購物車和費用的關係是多對一,通過gg gw...

MySQL IN 查詢優化

前幾天看到一篇博文將 in 子查詢 優化為 left join 的問題,今天自己測試測試。資料表為 test item 和 test item tag 兩個表 test item 兩個字段 item id char 36 release time int 11 共10w條記錄 test item t...

MySQL in和exists查詢對比

外表 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 t...