首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL IN 與 EXISTS 優化核心原則:小表驅動大表

     編輯:MySQL 綜合教學

核心原則

小表驅動大表:讓較小的結果集作為驅動表(外層迴圈),大表作為被驅動表(內層查找)。

執行邏輯對比

語法等價邏輯優勢場景
SELECT * FROM A WHERE id IN (SELECT id FROM B) FOR each row in B: SELECT * FROM A WHERE A.id = B.id B(子查詢)結果集 小於 A 時
SELECT * FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.id = A.id) FOR each row in A: SELECT * FROM B WHERE B.id = A.id A(主查詢)結果集 小於 B 時

實測案例

-- rocky_member 大表,rocky_vip_appro 小表(已過濾 passed=1)
-- 使用 EXISTS:0.313s
SELECT SQL_NO_CACHE * FROM rocky_member m
WHERE EXISTS (SELECT 1 FROM rocky_vip_appro a
              WHERE m.ID = a.user_id AND a.passed = 1);

-- 使用 IN:0.160s(快近一倍)
SELECT SQL_NO_CACHE * FROM rocky_member m
WHERE m.ID IN (SELECT ID FROM rocky_vip_appro WHERE passed = 1);

結論:子查詢表(rocky_vip_appro)資料量較小,IN 將其作為驅動表更高效。

關鍵前提

  • 關聯欄位(ID/user_id)必須建立索引,否則全表掃描導致效能崩塌。
  • NOT IN / NOT EXISTS 同理,但 NOT IN 若子查詢含 NULL 會導致結果為空,NOT EXISTS 較安全。

進階優化:NOT IN 改寫

針對大量資料的 NOT IN,建議改用 LEFT JOIN ... IS NULL 或 NOT EXISTS,並確保索引覆蓋,避免「天文數字」級的嵌套迴圈比較。

總結口訣

子查詢小 → 用 IN
主查詢小 → 用 EXISTS
關鍵欄位必加索引
NOT IN 慎用,優先 NOT EXISTS / LEFT JOIN

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved