非クラスター化インデックスに含まれる列に含める列と順序を決定するための厳格な規則はありますか?私はこの投稿を読んでいただけです https://stackoverflow.com/questions/1307990/why-use-the-include-clause-when-creating-an-index そして、次のクエリでそれを見つけました:
SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5
ポスターはこのように索引を作ることを提案しました:
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee(EmployeeID, DepartmentID)
INCLUDE (Lastname)
ここに私の質問が来ます、なぜこのようにインデックスを作成できないのですか?
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee( EmployeeID, DepartmentID, LastName)
または
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)
そして、LastName列を含めたままにすることを決定するようにポスターを導くものは何か。なぜ他のカラムではないのですか?そして、列をそこに保持する必要がある順序をどのように決定するのですか?
Marc_sによるそのインデックスの提案は間違っています。コメントを追加しました。 (そして、私の答えも受け入れられました!)
このクエリのインデックスは
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee(DepartmentID)
INCLUDE (Lastname, EmployeeID)
インデックスは通常
CREATE INDEX <name> ON <table> (KeyColList) INCLUDE (NonKeyColList)
どこ:
JNKとgbnは素晴らしい答えを出しましたが、単一のクエリだけに焦点を当てるのではなく、全体像を検討する価値もあります。この特定のクエリはインデックス(#1)の恩恵を受ける可能性がありますが、
Employee(DepartmentID) INCLUDE (Lastname, EmployeeID)
このインデックスは、クエリが次のようにわずかに変更された場合はまったく役に立ちません。
SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5 AND LastName = 'Smith'
これにはインデックスが必要です(#2):
Employee(DepartmentID, LastName) INCLUDE (EmployeeID)
部門5に1,000人の従業員がいるとします。含まれる列はキーの一部ではないため、インデックス#1を使用してすべてのスミスを見つけるには、部門5の1,000行すべてをシークする必要があります。インデックス#2を使用すると、部門5のLastName Smithを直接検索できます。
したがって、インデックス#2はより広い範囲のクエリを処理するのに役立ちますが、コストはより膨らんだインデックスキーになるため、インデックスの非リーフページが大きくなります。システムはそれぞれ異なるため、ここでは経験則はありません。
補足として、EmployeeIDがこのテーブルのクラスタリングキーである場合(クラスタ化インデックスを想定)、EmployeeIDを含める必要はありません。これは、すべての非クラスタ化インデックスに存在します。つまり、インデックス#2は、なる
Employee(DepartmentID, LastName)
どうやって最初のものを手に入れたのか分かりません。私にとって、そのクエリでは、次のように使用します。
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee(DepartmentID)
INCLUDE (EmployeeID, Lastname)
SQLのほとんど何にも「厳格な規則」はありません。
ただし、例では、インデックスがDepartmentID
句にあるため、インデックスが使用する唯一のフィールドはWHERE
です。
他のフィールドはそこから簡単にアクセスできる必要があります。 DepartmentID
に基づいて選択すると、INCLUDE
には、インデックスのリーフノードにこれらのフィールドがあります。
他の例はこのインデックスでは機能しないため、使用しないでください。
インデックスを電話帳のようなものと考えてください。ほとんどの電話帳は、姓、名、ミドルネームの順になっています。電話帳のインデックスの順序に基づいて名を検索することができないため、誰かの姓は知っているが姓は知らない場合、電話帳は役に立ちません。
INCLUDE
フィールドは、電話番号、住所など、書籍の各エントリのその他の情報に似ています。
編集:
使用しない理由をさらに明確にするには:
CREATE NONCLUSTERED INDEX NC_EmpDep
ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)
このインデックスは、EmployeeID
句にEmployeeID
または[〜#〜] both [〜#〜]LastName
およびWHERE
がある場合にのみ役立ちます。これは、このクエリに必要なものの[〜#〜] opposite [〜#〜]とほぼ同じです。
(employee_id、department_id)インデックスは引き続き使用できると思いますが、whereフレーズに「ダミー」行を含める必要があります。例: "employee_id = employee_id)
「古い」トリックを使用しますか?
従業員の従業員から*を選択します
where emp.employee_id = emp.employee_id
およびemp.department_id = 5
(したがって、ここではラストネームのインクルード部分に焦点を当てていませんが、はい/またはキーが使用されていないことに焦点を当てています。)
敬具、
ミゲル