主キーの代わりにカバー列を持つ一意の非クラスター化インデックスを使用することの意味


12

私たちは、大きなテーブル持っている[MyTable]現在の両方Aを有しPrimary KeyかつUnique Non Clustered Index同じ列に([KeyColumn])。U NCインデックスには、追加のカバー列もあります。

同じ列にPKと一意のNCインデックスの両方があることは冗長に思えるので、主キーを削除し、代わりに参照整合性の目的で一意の非クラスタ化インデックスを使用することを検討していました。

テーブルは別の列によって完全にクラスター化されることに注意してください。

つまり、次のとおりです。

ALTER TABLE [MyTable]
    ADD CONSTRAINT [PK_MyTable] 
    PRIMARY KEY NONCLUSTERED ([KeyColumn])
GO

そして

CREATE UNIQUE NONCLUSTERED INDEX [IX_MyTable_SomeIndex] 
    ON [MyTable] ([KeyColumn]) 
    INCLUDE ([Column1], [Column2])
GO

私の知る限り、主キーにカバー列を追加することはできないため、次のことを行います。

  • 依存する外部キー制約の削除 MyTable.KeyColumn
  • 主キーをMyTable.KeyColumn完全にドロップします
  • テーブルに外部キーを再追加します(RIはを介して強制されますMyTable.KeyColumn

これを考えることができる唯一の意味は、ERDダイアグラムに視覚的なキーシンボルが表示されず、列が含まれているため(リーフ)インデックス密度が低くなるということです。

/programming/487314/primary-key-or-unique-indexを読んで、これを行うことの整合性とパフォーマンスの側面に満足しています。

私の質問は次のとおりです。このアプローチには欠陥がありますか?

私が達成しようとしていることを編集します:パフォーマンス最適化と春の掃除。PKまたはインデックスのいずれかを削除すると、インデックスに必要なページが少なくなり、書き込みが高速になり、さらにメンテナンス/運用上の利点が得られます。

これにいくらかの背景を置くために、私はこれまでに、PKなしで参照されているテーブルを持っていませんでした。ただし、列をカバーするNCインデックスがテーブルに追加されたという事実は、自分の考え方を適応させる必要があることを意味します。


達成しようとしていることについてコメントしていただけますか?また、最後にクラスター化インデックスが作成されることを確認する必要があります。

@ jn29098-更新。PK列でもカバー列でもない列にクラスター化インデックスがあることを確認したため、これはこの決定に関連していないようです。
StuartLC

1
PKがなくなったことを確認したときにバーフするツール/ ORM /データ生成モデリングツールがないことを確認してください。
レムスルサヌ

唯一の欠点は、PKがなくなると、キー列に1つのインデックスがあり、PKインデックスを使用しているクエリは、キー列のインデックススキャンまたはキー列による順序付けに使用され、Uniuqeインデックスによってカバーされないため、余分なIOが発生する可能性があることですそれが見えるユニーク索引リーフ・ページがはるかにPK.Otherwiseのそれよりもあるようfine.Butは、いくつかの純粋主義者は、あなたがPK :)が必要と言うだろう
グルリMeel

1
インデックスの使用状況統計DMVを使用してそのインデックスの有用性を確認し、一部のクエリで使用されているかどうかを確認することをお勧めします。一意のキーインデックスに対しても確認し、それを使用してクエリに何が起こるかを決定します。インデックス..
グリーミール

回答:


3

パフォーマンスの最適化。PKまたはインデックスのいずれかを削除すると、インデックスに必要なページが少なくなり、書き込みが高速になり、さらにメンテナンス/運用上の利点が得られます。

提案されていることが実際に役立つことを証明できる必要があります(費用対利益)。この変更はどのような理由で検討されていますか?このテーブルには実際にパフォーマンスの問題がありますか、それとも単に「間違って見える」のですか?

環境に最適な決定を下すのに役立つその他の質問を次に示します。

  • メンテナンス時間はどのくらい節約されますか?バックアップウィンドウで?

  • これでどれくらいのストレージ容量が節約されますか(データファイル、ログファイル、バックアップなど)?

  • 現在、INSERTこのテーブルのパフォーマンスは本当にボトルネックですか?どの程度改善されますか?インデックスを削除することは、その問題を解決するための最良の戦略ですか?

  • これにより、各テーブルに一意のインデックスだけでなく主キーがあることを期待するデータベースツールおよびフレームワーク(特にORM)で問題が発生しますか?トランザクションレプリケーションで、公開されたテーブルにプライマリキーが必要です。

  • 自己文書化データベーススキーマは重要ですか?

  • 使用は限られていますが、主キーインデックスの狭さにより、オプティマイザーは特定のクエリに対してより効率的なプランを作成できますか?(使用するsys.dm_db_index_usage_stats調べるためにします。)

個人的に言えば、あなたが私たちに言ったことから、(a)余分なインデックスが問題であり、(b)それを取り除くことが解決策であることが証明できるまで、私はそれを放っておきます。


ありがとう-インデックスの統計では、PKがスキャンにまだ多く使用されていることがわかりました。PKを保持することの読みやすさ/慣習上の利点は、長期的にはストレージへの影響を上回るはずです。ただし、トランザクションレプリケーションに関するポイントはそれを簡潔にします。このデータベースをまもなく複製する必要があります。
StuartLC

2

そのテーブルでパフォーマンスが低下する(そしてわずかに悪化する)クエリのタイプは、KeyColumn値の範囲を要求するクエリだけです。現時点でこれらのクエリは、PK全体のインデックスシークによって最適に処理されるためです。

このテーブルを参照するテーブルの参照整合性チェックのコストが高くなる(ここでもわずかに高い)ことに注意してください。

nullableの側面を処理している限り、1つのインデックスで十分です。

それが私のDBである場合、おそらく他のすべてが同じである単一の一意のインデックスを使用します。


ありがとう-参照リンクはありますか?やや悪いですが、カバリングインデックスの低いインデックス密度のみを参照していますか、またはこれを引き起こす他の何かがありますか?
StuartLC

残念なことに多くの経験からであり、長年にわたって私よりもはるかに賢い人々とチャットしています!はい、それはまさにそれです-ページあたりの行数が少なくなるため、I / Oが増えます。ただし、INCLUDE列はリーフレベルにのみ存在することに注意してください。だからそれはすべて悪いわけではありません。あなたの質問の詳細に基づいてあなたはそれを知っていると確信していますが、他の読者はそうではないと推測しています。
マットホイットフィールド

-2

私の知る限り、主キーにカバー列を追加することはできません

KeyColumnにクラスター化インデックスがある場合、それはクラスター化インデックスであるため、他のすべての列は暗黙的に「カバー」されます。そのため、KeyColumnに別のインデックスを追加しても何も得られません。実際、挿入を遅くし、より多くのスペースを使用します。

これは、クラスタ化インデックスはインデックスそのものではなく、インデックスの順序でテーブルの行を格納するための単なる命令であるためです。そして、主キーで行を入力すると、他のすべての列がそこにあります。


2
最初の段落から:The table is clustered by another column entirely.
JNK

5
ここで主キー/クラスター化インデックスの混乱が発生している可能性があると思います。あなたを説得するための管理スタジオの最善の努力にもかかわらず、それらは同じものではありません。
マットホイットフィールド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.