我做了一些测试。我有两个表 - tableA(~3000 行)和 tableB(~200 行)。他们都有列ID。 TableA:ID - pk,TableB:ID - fk,非聚集索引。
从一张表中选择:
SELECT
a.ID
FROM
dbo.TableA a
WHERE
a.ID IN (1,5,7,9,23,45,56,546,67,32,54,676)
-- 执行计划:
|--Index Seek(OBJECT:([Database].[dbo].[TableA].[IX_TableA_ID] AS [a]), SEEK:([a].[ID]=(1) OR [a].[ID]=(5)) ORDERED FORWARD)
-- 统计 IO:
Table 'TableA'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
使用两个表选择(内连接)
SELECT
t.ID
FROM
dbo.TableA a
INNER JOIN
dbo.TableB t with(index(PK_TableBs)) ON t.ID = a.ID
WHERE
t.ID IN (1,5,7,9,23,45,56,546,67,32,54,676)
-- 执行计划:
|--Nested Loops(Inner Join, OUTER REFERENCES:([t].[ID]))
|--Clustered Index Seek(OBJECT:([Database].[dbo].[TableB].[PK_TableB] AS [t]), SEEK:([t].[ID]=(1) OR [t].[ID]=(5)) ORDERED FORWARD)
|--Index Seek(OBJECT:([Database].[dbo].[TableA].[IX_TableA_ID] AS [a]), SEEK:([a].[ID]=[Database].[dbo].[TableB].[ID] as [t].[ID]), WHERE:([Database].[dbo].[TableA].[ID] as [a].[ID]>=(1) AND [Database].[dbo].[TableA].[ID] as [a].[ID]<=(5)) ORDERED FORWARD)
-- 统计 IO:
Table 'TableA'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TableB'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
结果:
第二个查询成本是第一个查询 (33%) 的 67%(相对于批次)。
此外,第二个查询需要更多读取。
PS。这是一个肮脏的快速示例,您应该自己检查一下。