-1

(region_id, product_id, cate_id, month_id)主キーとして4つの列を持つテーブルがあります。この主キーはデフォルトで作成されているため、PK 用にクラスター化インデックスが作成されました。このテーブルには、1,000 万行を超える行が含まれています。

既存の pk を削除し、クラスター化されていないインデックス タイプで新しい pk を作成すると、次のクエリのクラスター化インデックスよりも優れていますか?

select region_id, product_id, cate_id, month_id, a, b, c 
from fact_a
where month_id > 100

前もって感謝します。

4

2 に答える 2

0

主キーを削除して (さらに、現在の複数列の主キーを単一の ID 列に置き換えて)、Month_ID で NCI を作成すると、より良い/より速く/より効率的になります。

クラスター化インデックス- それはデータです。テーブル内のすべての行のすべての列が含まれています。テーブル データが存在する必要があるのは 1 回だけであるため、存在できる CI は 1 つだけです。各行にはキーがあります...

主キー- クラスター化インデックス内の行を識別するためのキーです。

非クラスター化インデックス- クラスター化インデックスの行からの列のサブセットのテーブルとして機能します。

簡単に言うと、非クラスター化インデックスにはクラスター化インデックスよりも少ないデータが含まれており、CI (A、B、C、Month_ID) に対してクエリを実行するよりもはるかに効率的な方法 (Month_id ASC) でデータを並べ替えます。 )。SQL Server には、CI プライマリ キーまたは行データに「浸る」方法がなく、「ねえ、Month_ID でフィルタリングしているので、その列に直接移動します。」クラスター化インデックスの性質上、SQL Server はすべての CI 行 (インデックス スキャン)、すべての列、すべてのバイトのデータを "読み取り" ます。WHERE句がこれらの行の多くを除外するため、非常に非効率的で無駄です。

非クラスタ化インデックスには列のサブセットしか含まれていないため、「Month_ID でフィルタリングしていますが、Month_ID のみが含まれています。aaannnd Month_ID は昇順であるため、単純に私が望む行にジャンプしてください!」(インデックス シーク)。返したい行のみが SQL Server によって「読み取られる」ため、はるかに効率的です。

非クラスター化インデックスは Month_ID のみであるため、もう少し高度になりますが、クラスター化インデックスのすべての列に対してクエリを実行しているため、SQL Server は NCI から CI に戻って残りの列を取得できる必要があります。そのために、CI の主キーは、列サブセットと共に NCI に格納されます。したがって、NCI は (Month_ID、CI Primary Key) の 2 列のテーブルのようなものです。

プライマリ キーが巨大な場合、NCI も巨大になるため、効率が低下します (ディスク読み取りの増加、バッファー プールの消費量の増加、データベースの不良)。

免責事項: すべての列をクラスター化インデックス キー/pk にする特定のシナリオが存在する可能性があります。ここでは当てはまらないと思いますが、可能です。where 句または結合でテーブルのすべての列を参照する頻繁に使用されるクエリがある場合は、カバレッジ クラスター化インデックスが役立つ場合があります。

于 2015-03-06T21:23:40.217 に答える