web-dev-qa-db-ja.com

SQL主キーとインデックス

データベースにIDキー(int)が主キーとして設定されているとします。 IDからクエリを頻繁に行う場合、インデックスを作成する必要もありますか?それとも、それが主キーであるということは、すでに索引付けされているということですか?

私が尋ねる理由は、MS SQL ServerではこのIDにインデックスを作成できるからです。

編集:追加の質問-主キーに追加のインデックスを作成しても害はありませんか?

97
danifo

確かに、SQL Serverで同じフィールドに重複したインデックスを作成できるのは紛らわしいです。しかし、別のものを作成できるという事実は、PKインデックスがまだ存在していないことを示しているわけではありません。

追加のインデックスは効果がありませんが、唯一の害(非常に小さい)は、追加のファイルサイズと行作成のオーバーヘッドです。

65
dkretz

他の皆がすでに言ったように、主キーは自動的にインデックス付けされます。

主キー列にさらにインデックスを作成するのは、主キーと他の特定の列を使用するクエリを最適化する必要がある場合にのみ意味があります。主キー列に別のインデックスを作成し、それにいくつかの他の列を含めることにより、クエリの最適化を実現できます。

たとえば、多くの列を持つテーブルがありますが、ID、Name、およびAddress列のみをクエリしています。 IDを主キーとして、IDに基づいて構築された名前と住所の列を含む次のインデックスを作成できます。

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

したがって、このクエリを使用する場合:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL Serverは、作成したインデックスのみを使用して結果を提供し、実際のテーブルからは何も読み取りません。

44
red.clover

注:この回答は、エンタープライズクラスの開発に対応していますin-the-large

これはSQL ServerだけでなくRDBMSの問題であり、その動作は非常に興味深い場合があります。 1つは、主キーが自動的に(一意に)インデックス付けされるのが一般的ですが、絶対的なものではありません。 主キーが一意にインデックス付けされないことが不可欠な場合があります。

ほとんどのRDBMSでは、主キーに一意のインデックスが存在しない場合に自動的に作成されます。したがって、プライマリキーとして宣言する前に、プライマリキー列に独自のインデックスを作成し、プライマリキー宣言を適用するときにデータベースエンジンによってそのインデックスが使用されます(許容される場合)。多くの場合、主キーを作成してデフォルトの一意のインデックスを作成し、その列に独自の代替インデックスを作成してから、デフォルトのインデックスを削除できます。

さて、おもしろい部分です。一意の主キーインデックスが必要にならないのはいつですか。テーブルが十分なデータ(行)を取得し、インデックスのメンテナンスが高すぎる場合、1つは必要ありません。これは、ハードウェア、RDBMSエンジン、テーブルとデータベースの特性、およびシステム負荷によって異なります。ただし、通常は、テーブルが数百万行に達すると顕在化し始めます。

重要な問題は、行の挿入または主キー列の更新の結果、一意性を確保するためにインデックススキャンが行われることです。そのユニークなインデックススキャン(またはRDBMSでの同等のスキャン)は、テーブルのパフォーマンスを支配するまで、テーブルが大きくなるにつれてより高価になります。

この問題は、1日あたり20億行、8 TBのストレージ、4,000万行の挿入という大きなテーブルで何度も対処しました。関係するシステムを再設計する仕事がありました。これには、ステップ1として一意の主キーインデックスを実質的に削除することが含まれていました。実際、本番環境では、再設計が行われる前に、停止から回復するために、インデックスを削除する必要がありました。その再設計には、主キーの一意性を確保し、データへの迅速なアクセスを提供する他の方法を見つけることが含まれていました。

27
Rob Williams

主キーは常にデフォルトで索引付けされます。

SQL Server Management StudioまたはTransact-SQLを使用して、SQL Server 2012で主キーを定義できます。主キーを作成すると、対応する一意のクラスター化インデックスまたは非クラスター化インデックスが自動的に作成されます。

http://technet.Microsoft.com/en-us/library/ms189039.aspx

18
jcollum

非クラスター化を指定しない限り、PKはクラスター化インデックスになります

7
SQLMenace

ここでは [〜#〜] msdn [〜#〜] からのパッセージ:

テーブルにPRIMARY KEY制約を指定すると、データベースエンジンは、プライマリキー列に一意のインデックスを作成することにより、データの一意性を強制します。また、このインデックスを使用すると、クエリで主キーが使用されるときにデータに高速でアクセスできます。したがって、選択される主キーは、一意のインデックスを作成するためのルールに従う必要があります。

7
MicSim

それを主キーにすることで、自動的にインデックスを作成する必要があります。

2
E.J. Brennan

SQL Serverでは、通常、主キーは自動的にインデックス付けされます。これは事実ですが、クエリの高速化は保証されていません。主キーとしてフィールドが1つしかない場合、主キーは優れたパフォーマンスを提供します。ただし、主キーとして複数のフィールドがある場合、インデックスはそれらのフィールドに基づいています。

たとえば、フィールドA、B、Cが主キーであるため、WHERE CLAUSEのこれら3つのフィールドに基づいてクエリを実行するとパフォーマンスは良好ですが、WHERE CLAUSEのCフィールドのみでクエリを実行する場合は、良いパフォーマンスは得られません。したがって、パフォーマンスを向上させるには、Cフィールドに手動でインデックスを付ける必要があります。

ほとんどの場合、100万件を超えるレコードがヒットするまで、問題は表示されません。

1
Susanto Siman

PRIMARY KEYまたはUNIQUE制約を宣言すると、SQL Serverは自動的にインデックスを作成します。

制約に一致することなく一意のインデックスを作成できますが、一意のインデックスがなければ制約(主キーまたは一意)は存在できません。

ここから、制約の作成は次のようになります。

  • 同じ名前のインデックスを作成します
  • 制約はそれなしでは存在できないため、作成されたインデックスの削除を拒否します

同時に、制約を削除すると、関連するインデックスも削除されます。

それで、PRIMARY KEYまたはUNIQUE INDEXの間に実際の違いはありますか?

  • NULL値はPRIMARY KEYでは許可されませんが、UNIQUEインデックスでは許可されます。セット演算子(UNION、EXCEPT、INTERSECT)のように、ここでNULL = NULLは、2つのNULLsが相互の重複として検出されるため、1つの値しか持つことができないことを意味します。
  • 999 一意のインデックスを作成できますが、テーブルごとにPRIMARY KEYは1つしか存在できません
  • PRIMARY KEY制約が作成されると、テーブルにクラスター化インデックスが既に存在するか、その定義でNONCLUSTEREDが使用されていない限り、クラスター化されたものとして作成されます。 UNIQUEインデックスが作成されると、NONCLUSTEREDであることが特定されない限り、CLUSTEREDとして作成され、そのようなインデックスは既に存在しません。
1
gotqn

主キーは自動的に索引付けされます

用途に応じてpkを使用して追加のインデックスを作成できます

  • インデックスZip_code、idは、Zip_codeとidで頻繁に選択する場合に役立ちます。
0
mson

(別個の)インデックスのない巨大なデータベースがあります。

主キーでクエリを実行すると、すべての集中的な目的のために、結果は即座に取得されます。

0
Grant