問題

Table ScanClustered Index Scanの両方が本質的にテーブル内のすべてのレコードをスキャンするので、なぜクラスタリングインデックススキャンが優れているのでしょうか?

例として - 多くのレコードがある場合のパフォーマンスの違いは何ですか?

 declare @temp table(
    SomeColumn varchar(50)
)

insert into @temp
select 'SomeVal'

select * from @temp

-----------------------------

declare @temp table(
    RowID int not null identity(1,1) primary key,
    SomeColumn varchar(50)
)

insert into @temp
select 'SomeVal'

select * from @temp
 

  ベストアンサー

クラスタ化されたインデックス(ヒープテーブル)のないテーブルでは、データページは一緒にリンクされていないため、トラバースページにはルックアップが必要です インデックス割り当てマップ

ただし、クラスタ化されたテーブルには、のデータページが二重リンクリストにリンクされています。シーケンシャルスキャンを少し速くします。もちろん、その代わりに、INSERTUPDATEDELETEの順序でデータページを保持するオーバーヘッドがあります。しかし、ヒープテーブルでは、choserに2番目の書き込みが必要です。

あなたのクエリにRANGE演算子(例:SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100)がある場合、クラスタ化されたテーブル(保証された順序である)は、インデックスページを使用して関連するデータページを見つけることができるため、より効率的です。ヒープは順序に依存しないため、すべての行をスキャンする必要があります。

もちろん、クラスタ化されたインデックスでは、パフォーマンスに最適なCLUSTERED INDEX SEEKを実行できます...インデックスのないヒープは常にテーブルスキャンになります。

そう:

  • すべての行を選択するクエリの例では、唯一の違いは、クラスタ化されたインデックスが維持する双方向リンクリストです。これにより、クラスタ化されたテーブルは、多数の行を持つヒープよりもわずかに高速になります。

  • クラスタ化インデックスによって(少なくとも部分的に)満足できるWHERE句を持つクエリでは、順序付けのために先に出てくるので、テーブル全体をスキャンする必要はありません。

  • クラスタ化されたインデックスによって満たされていないクエリの場合、あなたはかなり多くのものです...繰り返しますが、唯一の違いは、シーケンシャルスキャンのための二重リンクリストです。いずれの場合も、最適ではありません。

  • INSERTUPDATE、およびDELETEの場合、ヒープは勝つかもしれません。ヒープは順序を維持する必要はありませんが、2番目の書き込みが必要です。相対的なパフォーマンスの違いは無視できると思いますが、かなりのデータに依存します。

Microsoftには、クラスタ化されたインデックスをヒープ上の同等の非クラスタ化インデックスと比較する whitepaper があります(上記とまったく同じではありませんが、閉じています)。彼らの結論は、基本的にすべてのテーブルにクラスタ化インデックスを配置することです。私は結果を要約するために最善を尽くします(ここでは、クラスタ化されていないインデックスとクラスタ化

  • INSERTパフォーマンス:クラスタ化インデックスは、ヒープに必要な2番目の書き込みにより約3%勝ちます。
  • UPDATE パフォーマンス:クラスタ化インデックスは、ヒープに必要な2番目のルックアップのために約8%勝ちます。
  • DELETEパフォーマンス:クラスタ化インデックスは、必要な2番目のルックアップとヒープのために必要な2番目の削除により約18%勝ちます。
  • 単一のSELECTパフォーマンス:クラスタ化インデックスは、ヒープに必要な2番目のルックアップのために約16%勝ちます。
  • 範囲SELECTのパフォーマンス:ヒープのランダムな順序により、クラスタ化インデックスが約29%勝ちます。
  • Concurrent INSERT:ヒープテーブルは、クラスタ化インデックスのページ分割による負荷の30%に勝ちます。

  同じタグがついた質問を見る

sqlsql-serverindexing