0

次のように luTab から myTab を更新する必要があるとします。

update myTab
  set LookupVale = (select LookupValue from luTab B
                                       where B.idLookup = myTab.idLookup)

luTab は 2 つの列 (idLookup(unique)、LookupValue) で構成されます。

idLookup の一意のクラスター化インデックス、または idLookup と Lookupvalue の組み合わせのどちらが望ましいですか? この状況でカバリングインデックスは何か違いを生むでしょうか?

(私は主にSQLサーバーに興味があります)


エピローグ :

以下の Krips テストを、myTab で 2700 万行、luTab で 150 万行でフォローアップしました。重要な部分は、インデックスの一意性にあるようです。インデックスが一意として指定されている場合、更新ではハッシュ テーブルが使用されます。一意として指定されていない場合、更新は最初に idLookup (ストリーム アグリゲート) によって luTab を集約し、次にネストされたループを使用します。これははるかに遅いです。拡張インデックスを使用すると、その LookupValue が一意であると SQL が保証されなくなり、はるかに低速なストリーム集約ネスト ループ ルートが強制されます。

4

2 に答える 2

2

まず:

  • カバーするインデックスは常に非クラスター化されます
  • 常にPKとクラスター化インデックスが必要です(SQL Serverにはデフォルトで同じものがあります)

2つの概念は別々です

それで:

  • これが行を一意に識別する場合、PK(クラスター化)はidLookupになります
  • カバーするインデックスは(idLookup)INCLUDE(LookupValue)になります

でも:

  • idLookupはPK(クラスター化)であるため、カバーするインデックスは必要ありません
  • クラスター化されたインデックス(PK)は、クラスター化されたインデックスの性質によって暗黙的に「カバー」されます(単純に、インデックスは最下位レベルのデータです)
于 2009-12-18T10:53:33.513 に答える
1

テーブルを作成し、いくつかのレコードをロードしました(50程度のルックアップ、およびmyTabで15)。

次に、さまざまなインデックスオプションを試しました。luTabのインデックスシークのコストは常に29%です。

興味深い点は、LookupValue列をluTabのインデックスに追加すると、実行プランにインデックスシークの後に2つの追加ステップ(Stream AggregateとAssert)が表示されることです。コストは0%ですが、データが増えると上昇する可能性があります。

また、idLookupだけで非クラスター化インデックスを試し、LookupValueを「含まれる列」として含めました。そうすれば、その列を取得するためにデータページにアクセスする必要がなくなります。実行プランには何も違いはありませんが、これはオプションかもしれません(ただし、Stream Aggregate / Assertもありません)。

-クリップ

于 2009-12-18T10:54:46.007 に答える