web-dev-qa-db-ja.com

複合主キー-両方のフィールドにインデックスを付けますか?

ユーザーとロールの間に多対多の結合テーブルがあります。

CREATE TABLE AppUserRole 
(
    UserId INT NOT NULL,
    RoleId INT NOT NULL, 

    CONSTRAINT PK_AppUserRole PRIMARY KEY (UserId, RoleId), 

    CONSTRAINT FK_AppUserRole_User FOREIGN KEY (UserId) 
        REFERENCES AppUser(UserId), 
    CONSTRAINT FK_AppUserRole_Role FOREIGN KEY (RoleId) 
        REFERENCES AppRole(RoleId)
);

CREATE INDEX IX_AppUserRole_RoleId ON AppUserRole(RoleId)
CREATE INDEX IX_AppUserRole_UserId ON User(UserId)

複合キーは(UserIdRoleId)の順序でクラスター化されているので、UserIdの2番目のインデックスは本当に必要ですか?

特定のUserIdのすべての行をクエリすると、クラスター化インデックスが使用されます。特定のRoleIdのすべてのユーザーをクエリした場合のみ、インデックスIX_AppUserRole_RoleId 利用される。

インデックスですIX_AppUserRole_UserId必要ですか?

5
Richard

クエリは、列の順序でインデックスを使用します(最初にUserId、次にRoleId)。 RoleIdにインデックスがない場合は、クラスター化インデックスをスキャンします。 userIdを含むwhere句がない限り、エンジンは、すべてのuserIdをスキャンするインデックスの内部を取得する方法を知りません。

RoleIdはFKであるため、ベストプラクティスではインデックスを作成することをお勧めします。 (よく)クエリを実行する場合は、間違いなく必要です。

UserIdのインデックスだけでは役に立たない。 UserIdがエントリポイントであるため、クラスター化インデックスは既にそれを実行しています。これを使用しても、データまたは関連するroleIdを取得するために、PKへの追加のルックアップは必要ありません。クラスター化されたインデックスシーク。

3