in是把外表和內錶作hash連線,而exists是對外表作loop迴圈,每次loop迴圈一次對內表進行一次查詢。
如果查詢的兩個表大小相當,那麼用in和exists差別不大;如果兩個表中乙個較小乙個較大,則子查詢表大的用exists,子查詢錶小的用in;
注意: a表與b表的id欄位應建立索引
select * from a where id in (select id from b)
// in會使用子查詢結果去主表匹配需要的行。子查詢結果越大,去主表索引(a表上id列的索引)中檢索的次數越多,效率越低1 2
等價於:
for select id from b
for select * from a where a.id = b.id
// 比如:a表有5條記錄,b表裡有4萬條記錄,in會迴圈用4萬個資料(id)去匹配這5條記錄,成本遠比用5條資料(id)去匹配4萬條記錄效率低1 2 3select * from a where exists (select 1 from b where b.id = a.id)
// exists是根據匹配項去判斷是或者否,然後根據是否決定結果,子查詢的表大,用exists判斷,效率就會高1 2
等價於for select * from a
for select * from b where b.id = a.id
//比如:a表有5條記錄,b表裡有4萬條記錄,exists只進行5次判斷,比in快很多。1 2 3
結論:當a表的資料集小於b表的資料集時,用exists優於in。
select * from a where id in(select id from b) //效率高
select * from a where exists(select cc from b where cc=a.id) //效率低1 2 3
結論:當b表的資料集小於a表的資料集時,用in優於exists。
not in 和not exists如果查詢語句使用了not in 那麼內外表都進行全表掃瞄,沒有用到索引;而not extsts 的子查詢依然能用到表上的索引。所以無論那個表大,用not exists都比not in要快。
網上還有人說mysql5.6版本對in查詢做了很好的優化,所以效率問題要看具體的場景,要看真實測試的資料來進行優化!
如果in和or所在列有索引或者主鍵的話,or和in沒啥差別,執行計畫和執行時間都幾乎一樣。
如果in和or所在列沒有索引的話,效能差別就很大了。在沒有索引的情況下,隨著in或者or後面的資料量越多,in的效率不會有太大的下降,但是or會隨著記錄越多的話效能下降非常厲害。
因此在給in和or的效率下定義的時候,應該再加上乙個條件,就是所在的列是否有索引或者是否是主鍵。如果有索引或者主鍵效能沒啥差別,如果沒有索引,效能差別不是一點點!
MySQL高階之索引
索引是一種特殊的檔案 innodb資料表上的索引是表空間的乙個組成部分 它們包含著對資料表裡所有記錄的引用指標。更通俗的說,資料庫索引好比是一本書前面的目錄,能加快資料庫的查詢速度 索引的目的在於提高查詢效率,可以模擬字典,如果要查 mysql 這個單詞,我們肯定需要定位到m字母,然後從下往下找到y...
MySQL高階高階
1 mysql的開窗函式 row number 從 1 開始,按照順序生成組內的記錄編號 rank 從 1 開始,按照順序,相同會重複,名次會留下空的位置,生成組內的記錄編號 dense rank 從 1 開始,按照順序生成組內的記錄編號,相同會重複,名次不會留下空的位置 開窗函式區別如下圖所示 f...
mysql 高階 mysql高階知識
一.儲存引擎 引擎 指的是乙個系統的核心部分 引擎有不同分類是為了適應不同的使用場景 檢視mysql支援所有引擎 show engines mrg myisam 是一堆myisam表的集合 用於做水平分表,如果乙個表中資料量太大 將導致效率降低 水平分表就是把整個大表拆成不同的小表,每一次查詢 會判...