私はいくつかのテストを行いました。テーブルA(〜3000行)とテーブルB(〜200行)の2つのテーブルがあります。どちらにも列IDがあります。TableA: ID - pk、TableB: ID - fk、非クラスター化インデックス。
1 つのテーブルから選択:
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.
2 つのテーブルを使用して選択する (内部結合)
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.
結果:
2 番目のクエリのコストは、最初のクエリ (33%) に対して 67% (バッチに対して) です。また、2 番目のクエリでは、より多くの読み取りが必要です。
PS。これは簡単な例です。自分で確認してください。