ユニーク制約

アーキテクチャ徹底解説 SQL SERVER2000 (マイクロソフト公式解説書)のp.467より引用。

PRIMARY KEY制約またはUNIQUE制約を宣言すると、CREATE INDEXコマンドを使用した場合と同様に、1つまたは複数の列に一意のインデックスが作成される。これらの制約を宣言して作成されたインデックスの名前は、制約の名前と同じになる。インデックスの内部記憶領域と維持に関する限り、CREATE INDEXコマンドを使用して作成された一意のインデックスと、制約を宣言して作成されたインデックスの間にはまったく差異がない。

へー。UNIQUE制約を宣言すると一意インデックスが作成されるのですね。

UNIQUE制約によって作成された一意インデックスが実行計画で使われるか確かめてみます。

パターン5: ユニーク制約を使う場合
パターン3での一意インデックスに相当するユニーク制約を作成して前々回のクエリを実行します。

ALTER TABLE [BelongTo] 
WITH CHECK 
ADD CONSTRAINT [UQ_BelongTo_EmployeeID_DepartmentID] 
UNIQUE([EmployeeID], [DepartmentID])

実行計画は次のようになりました。

  |--Nested Loops(Inner Join, OUTER REFERENCES:([sql].[dbo].[BelongTo].[DepartmentID]))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([sql].[dbo].[Employee].[EmployeeID]))
       |    |--Clustered Index Scan(OBJECT:([sql].[dbo].[Employee].[PK__Employee__30592A6F]), WHERE:([sql].[dbo].[Employee].[EmployeeNo]=N'Employee8-45'))
       |    |--Index Seek(OBJECT:([sql].[dbo].[BelongTo].[UQ_BelongTo_EmployeeID_DepartmentID]), SEEK:([sql].[dbo].[BelongTo].[EmployeeID]=[sql].[dbo].[Employee].[EmployeeID]) ORDERED FORWARD)
       |--Clustered Index Seek(OBJECT:([sql].[dbo].[Department].[PK__Department__324172E1]), SEEK:([sql].[dbo].[Department].[DepartmentID]=[sql].[dbo].[BelongTo].[DepartmentID]) ORDERED FORWARD)

インデックスの名前がちがうだけで実行計画はパターン3のときと同じです。
ちゃんとユニーク制約(の宣言によって作成されたインデックス)が使われています。