2011-12-26 6 views
1

通常、顧客がいずれかのフィールドを使用してレコードを検索する場合、テーブルのすべてのカラムをセカンダリインデックスにするかどうかは安全です。SQLテーブルの最適化:プライマリおよびセカンダリインデックス

検索は最初にセカンダリインデックスを通過してからプライマリキーに行きますか?したがって、要求されたデータを絞り込むことができますか?

すでに主キーである列を持っている場合、セカンダリインデックスを持つ点は何ですか?

+0

あなたの質問は、インデックスではなく、キーに関するように見えます。それは他人がそれを解釈した方法であり、私はそれに応じて質問を編集しました。私の編集を元に戻して、実際に鍵について質問するのであれば、あなたの質問を明確にしてください。 – sqlvogel

答えて

1

通常、必要な列のみを索引付けします。索引を追加することは通常、時期尚早の最適化と見なされます。

ほとんどのオプティマイザは、最も少ないレコード数を見つける最も速い方法を特定します。これは、使用および索引付けである可能性がありますが、全表スキャンである可能性があります。使用可能な索引が複数ある場合は、1つのみが使用され、結果のレコードは残りの基準と比較されます。複数の索引が使用されている場合は、結果の結果セットを一致させる必要があり、両方の索引で見つからなかったレコードは削除されます。

自然キーが変更されるか、非常に(意図的に曖昧な)長いテーブルの代用キーを使用するのが一般的です。この場合の自然キーは、二次固有キーとして索引付けされます。競合する自然キーが存在する場合もあります。この場合、すべての自然キーは一意のインデックスを持ちます。最初

0

「安全面」? No.

インデックスは、選択時にスペースと挿入時間を交換します。決して発生しないクエリの高速化のために、不要なキーがディスク領域を噛み砕き、挿入を遅くします。

すべての最適化と同様に、クエリの最適化が最後に - システムを構築し、その動作を観察します。

非常に専門的なものでは、プライマリ/セカンダリの区別。クエリを高速化したり、特定の整合性制約を実施するために、すべてのインデックスが存在します。

3

(次の応答では、SQL Serverに適用されるいくつかの部分は、他のDBMSのために異なる場合があります。。)

最後の質問:「あなたはすでに主キーである列を持っている場合は、二次キーを持つことのポイントは何ですか? "私はテーブルの例で説明します"People (Id int primary key, firstname varchar(40), middlename varchar(40), lastname varchar(40))".今度はクエリを考えてみましょう"select * from people where lastname = 'flynn'". lastnameカラムにインデックスがない場合、テーブルは順次検索されて一致するものが見つかります。すべての行にアクセスする必要があります。主キー索引は、ここではまったく役に立ちません。 lastname列に索引を付けると、結果がはるかに迅速に見つかります。

通常、アプリケーションが発行するクエリに役立つ列のみをインデックスします。クエリーに「MiddleName」という名前の列の結合またはwhere条件がない場合、その列をインデックス化することによるメリットはありません。不要な索引は、その列を含むデータの挿入および更新のコストを増加させるため、追加したくありません。

通常、Sql Serverはクエリでテーブルインスタンスごとに1つのインデックスのみを使用しています。だからfirstnameとlastnameの両方にインデックスがあっても、firstname = 'Elroy'とlastname = 'Flynn'のように "select * from people"のようなクエリは、多くとも1つのインデックスを使用します。 SQL Serverは、データ値から収集した統計に基づいて、1つまたは他のインデックスを選択します。

完全に完全には、私はここで少し進歩し、クラスタ化された非クラスタ化インデックス表には1つのクラスタード・インデックスしか存在できません。残りはクラスター化されていません。前の段落にもかかわらず、クエリを解決するためにクラスタ化されていないインデックスが使用されている場合、インデックスルックアップは、クラスタ化インデックス(多くの場合、プライマリキー)であるインデックスに関連付けられたキーの完全な値である中間結果を生成します。つまり、クラスタ化されていないすべてのインデックスの葉には、行ポインタではなくクラスター化されたキー値が含まれています。このクラスタ化されたキーを見つけた後、クラスタ化インデックスを使用して、特定のデータベース行に対するルックアップを解決します。最終的には、すべての索引ルックアップで最終的にクラスタード索引が使用されます。

実際、実際には、テーブルインスタンスごとに1つのインデックスしか使用されないと言うのは、通常は適切かつ簡単です。あるテーブルが複数回表示されるようにクエリ内でエイリアスが設定されている場合は、異なるインデックスに対して異なるインデックスを使用できます。例えば、「select * from people p1 join people p2 on p1.firstname = p2.lastname"がP1インスタンスとp2インスタンス上の姓指数にFIRSTNAMEインデックスを使用することができます。

はまだ言及していないhttp://msdn.microsoft.com/en-us/library/aa933131(v=SQL.80).aspx

1

もう一つの項目を参照して、すべての追加のインデックスが維持されなければならない。だからもしいくつかの異なる組み合わせですべての列をカバーするインデックスを持っているだけでなく、更新/挿入/削除がそれぞれ1つ以上のインデックスを変更する可能性があるため、これらの操作が遅くなります多くの状況があります。

これは常にトレードオフです。インデックスを増やすほど、最新の状態に保つためにサーバーが必要とする作業が増えますしかし、あなたがそのテーブルで投げるクエリをカバーするものを少なくとも1つは持っている可能性が高くなります。