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

SQL Server EXISTS vs IN 深度解析:效能差異與適用場景

     編輯:關於SqlServer

IN 與 EXISTS 常用於子查詢,但優化策略不同,效能表現隨資料分布、索引、NULL 值而異。本文透過實測說明核心差異。

核心結論速查表

場景建議原因
NOT IN vs NOT EXISTS優先用 NOT EXISTSNOT IN 若子查詢含 NULL 則無列回傳;NOT EXISTS 可用連接演算法
IN vs EXISTS小表驅動大表用 IN,大表驅動小表用 EXISTSIN 傾向轉為 JOIN(Hash/merge join);EXISTS 採用相關子查詢(Nested Loops)
子查詢回傳大量列EXISTSEXISTS 只要找到一筆即停止,不需完整掃描

實測環境建立

CREATE TABLE #tempTable1 (argument1 NVARCHAR(50), argument2 VARCHAR(20), argument3 DATETIME, argument4 INT);
CREATE TABLE #tempTable2 (argument1 NVARCHAR(50), argument2 VARCHAR(20), argument3 DATETIME, argument4 INT);

-- 插入測試資料(略,見原文)

案例 1:求交集

-- IN 寫法
SELECT * FROM #tempTable2 WHERE argument1 IN (SELECT argument1 FROM #tempTable1);

-- EXISTS 寫法
SELECT * FROM #tempTable2 t2 
WHERE EXISTS (SELECT 1 FROM #tempTable1 t1 WHERE t1.argument1 = t2.argument1);

兩者執行計畫通常相同(Hash Match 或 Merge Join),效能接近。

案例 2:求差集(在 Table1 不在 Table2)

-- NOT IN:若子查詢含 NULL,整個結果為空!極危險
SELECT * FROM #tempTable1 WHERE argument1 NOT IN (SELECT argument1 FROM #tempTable2);

-- NOT EXISTS:安全、可用索引、效能穩定
SELECT * FROM #tempTable1 t1 
WHERE NOT EXISTS (SELECT 1 FROM #tempTable2 t2 WHERE t1.argument1 = t2.argument1);

關鍵陷阱:NOT IN + NULL

SELECT * FROM t1 WHERE col NOT IN (SELECT col FROM t2); 
-- 若 t2.col 有任一 NULL,結果永遠為 0 列

NOT EXISTS 不受 NULL 影響,語意更直觀。

最佳實務建議

  • 差集查詢永遠用 NOT EXISTS。
  • 交集查詢:小結果集驅動大表用 IN,大表驅動小表用 EXISTS。
  • 子查詢加 SELECT 1 而非 SELECT *,減少元資料開銷。
  • 確保連接欄位有索引,並避免隱含轉換。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved