テーブルスキャンとクラスター化インデックススキャンの違いは何ですか?
質問
というのは
Table Scan
と
Clustered 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
どのように解決するのですか?
クラスタ化インデックスのないテーブル (ヒープ テーブル) では、データ ページは互いにリンクされていません - そのため、ページをたどるには インデックス アロケーション マップへのルックアップが必要です。 .
しかし、クラスタ化されたテーブルには
データページが二重リンクリストにリンクされ
- でリンクされており、シーケンシャルスキャンが少し速くなります。もちろん、それと引き換えに、データページを
INSERT
,
UPDATE
そして
DELETE
. しかし、ヒープテーブルは、IAMへの2回目の書き込みが必要です。
もしあなたのクエリが
RANGE
演算子(例.
SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100
) の場合、クラスタ化されたテーブル (順序が保証されている) の方が効率的でしょう - なぜなら、インデックスページを使用して関連するデータページを見つけることができるからです。ヒープでは、順序に依存できないため、すべての行をスキャンする必要があります。
そしてもちろん、クラスタ化されたインデックスはCLUSTERED INDEX SEEKを行うことができ、これはパフォーマンスにとってかなり最適です...インデックスを持たないヒープは常にテーブルスキャンを行うことになります。
というわけで。
-
すべての行を選択する例のクエリでは、唯一の違いはクラスタ化インデックスが保持する二重リンクリストです。これにより、クラスタ化されたテーブルは、多数の行を持つヒープよりもほんの少し速くなるはずです。
-
を持つクエリに対して
WHERE
句を持つクエリでは、クラスタ化インデックスによって(少なくとも部分的に)満たされるため、テーブル全体をスキャンする必要がなく、順序付けによって優位に立つことができます。 -
クラスタ化インデックスによって満たされないクエリでは、ほぼ互角です。唯一の違いは、順次走査のための二重リンクされたリストがあることです。どちらの場合でも、最適とは言えません。
-
については
INSERT
,UPDATE
そしてDELETE
で、ヒープが勝つかもしれないし、勝てないかもしれない。ヒープは順序を維持する必要はありませんが、IAMへの2回目の書き込みが必要です。相対的なパフォーマンスの違いはごくわずかだと思いますが、かなりデータに依存します。
マイクロソフトは ホワイトペーパー で、ヒープ上のクラスタ化インデックスと同等の非クラスタ化インデックスを比較しています(私が上記で説明したものと全く同じではありませんが、近いです)。彼らの結論は、基本的にすべてのテーブルにクラスタ化インデックスを配置することです。彼らの結果を要約するために最善を尽くします(ここでも、彼らは実際には非クラスタ化インデックスとクラスタ化インデックスを比較していることに注意してください - しかし、私はそれが比較的同等だと思います)。
-
INSERT
パフォーマンス: ヒープに必要な 2 番目の書き込みにより、クラスタ化されたインデックスが約 3% 優れています。 -
UPDATE
パフォーマンス: ヒープに必要な 2 番目のルックアップにより、クラスタ化されたインデックスが約 8% 優位になります。 -
DELETE
パフォーマンス: クラスタ化されたインデックスは、ヒープのために IAM から必要とされる 2 番目のルックアップと 2 番目の削除により、約 18% の差で勝利します。 -
シングル
SELECT
パフォーマンス: ヒープに必要な 2 番目のルックアップにより、クラスタ化されたインデックスが約 16% 優れています。 -
範囲
SELECT
パフォーマンス: クラスタ化されたインデックスは、ヒープに対するランダムな順序付けにより、約29%勝っています。 -
同時並行
INSERT
: ヒープ テーブルは、クラスタ化インデックスのページ分割により、負荷がかかると 30% 勝つことができます。
関連
-
解決策:ユーザー root で localhost:3306 にある MySQL に接続できませんでした。
-
[解決済み] リスト内のアイテムのインデックスを検索する
-
[解決済み] UNIONとUNION ALLの違いは何ですか?
-
[解決済み] varcharとnvarcharの違いは何ですか?
-
[解決済み] JOINとINNER JOINの違いについて
-
[解決済み] クラスター化インデックスと非クラスター化インデックスの実際の意味は何ですか?
-
[解決済み] SQL Serverでレコードを削除した後、IDシードをリセットする。
-
[解決済み] Postgres でサブクエリを使用してテーブルの行を更新する
-
[解決済み】「INNER JOIN」と「OUTER JOIN」の違いは何ですか?
-
[解決済み】クラスタ化インデックスと非クラスタ化インデックスの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
MySQL - ストアドプロシージャ (データ型、関数)
-
executeQuery()ソリューションでデータ操作文を発行できない。
-
[解決済み] MySQLの「スキーマの作成」と「データベースの作成」 - 違いはあるのか?
-
[解決済み] Oracleの全テーブルのリストを取得しますか?
-
[解決済み] SQL Serverにおける関数とストアドプロシージャの比較
-
[解決済み] mysqldumpで特定のテーブルをスキップする
-
[解決済み] SQLite - UPSERT *not* INSERT or REPLACE
-
[解決済み] 項目xにアクセスできるように文字列を分割するにはどうすればよいですか?
-
[解決済み] SQLサーバーで行を列に効率的に変換する
-
[解決済み] Entity Framework VS LINQ to SQL VS ADO.NETでストアドプロシージャを使う?[クローズド]