测试In & Exists & Join 的性能
Step 1. 测试环境搭建
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
Enterprise Edition (64-bit) on Windows NT 6.1
-- IN & EXISTS & INNER JOIN
TABLE BIG_TB
3: (
KEY,
NULL
6: )
7:
TABLE SMALL_TB
9: (
KEY,
NULL,
DEFAULT(GETDATE())
13: )
14:
15:
INTO BIG_TB (Col)
top 250000
char(65+FLOOR(RAND(b.column_id *2222 + b.object_id)*12)) +
char(65+FLOOR(RAND(a.column_id *4444 + b.object_id)*8))
join master.sys.columns b;
GO
22: --250000
23:
24:
INTO SMALL_TB (col)
DISTINCT col
PERCENT);
GO
29: --2807
Step 2.测试代码
Index =====================
FROM BIG_TB
FROM SMALL_TB)
4:
FROM BIG_TB
WHERE SMALL_TB.col = BIG_TB.col)
7:
FROM BIG_TB A
ON A.col = B.col
10:
11:
Exists
FROM BIG_TB
FROM SMALL_TB)
15:
FROM BIG_TB
WHERE SMALL_TB.col = BIG_TB.col)
18:
FROM BIG_TB A
ON A.col = B.col
NULL
22:
23:
Index =====================
INDEX idx_BIG_TB_col
ON BIG_TB (col)
27:
INDEX idx_SMALL_TB_col
ON SMALL_TB (col)
30:
31:
FROM BIG_TB
FROM SMALL_TB)
34:
FROM BIG_TB
WHERE SMALL_TB.col = BIG_TB.col)
37:
FROM BIG_TB A
ON A.col = B.col
40:
41:
Exists
FROM BIG_TB
FROM SMALL_TB)
45:
FROM BIG_TB
WHERE SMALL_TB.col = BIG_TB.col)
48:
FROM BIG_TB A
ON A.col = B.col
IS NULL
Step 3.测试数据汇总
总结: 在有无Index的前提下,In/Exists及Not In/Not Exists的性能表现相差无几。 而Inner Join/Left Outer Join则相较而言,性能表现上稍微较慢。但注意到Col列 是Not Null属性的。当该列为Nullable状态时,Not Exists与Not In的处理方式将 有所不同,性能表现见下表:
TABLE BIG_TB
NULL
3:
TABLE SMALL_TB
NULL
6:
7:
8:
FROM BIG_TB
FROM SMALL_TB)
11:
/*
表 'SMALL_TB'。扫描计数 13,逻辑读取 500058 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'BIG_TB'。扫描计数 5,逻辑读取 3992 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
15:
SQL Server 执行时间:
CPU 时间 = 1095 毫秒,占用时间 = 306 毫秒。
*/
19:
20:
FROM BIG_TB
WHERE SMALL_TB.col = BIG_TB.col)
/*
表 'BIG_TB'。扫描计数 1,逻辑读取 3639 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'SMALL_TB'。扫描计数 1,逻辑读取 9 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
26:
27:
SQL Server 执行时间:
CPU 时间 = 265 毫秒,占用时间 = 263 毫秒。
*/
又上述数据可以看出。在处理含有null的数据时,Not exists 的性能将比Not In的性能有很大提升。提升效率大约为5倍左右。