0

数百万のレコードを持つ、2 つの列を持つ多対多のリンク テーブル CategoryProduct があります。

CREATE TABLE [dbo].[CategoryProduct](
[Category_ID] [int] NOT NULL,
[Product_ID] [int] NOT NULL,
CONSTRAINT [PK_dbo.CategoryProduct] PRIMARY KEY CLUSTERED 
(
    [Category_ID] ASC,
    [Product_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

クラスター化インデックスに基づいて、物理レコードが次の構造で格納されることを期待しました。

CategoryID    ProductID
1             2
1             3
2             1
2             3

ただし、Select の結果は

CategoryID    ProductID
2             1
1             2
1             3
2             3

ProductID のグループにデータが格納されるのはなぜですか? これはデータの実際の順序を反映していますか? 一致する CategoryID がヒットしたときに、以下のようなクエリを連続読み取りで最適化できるように、CategoryID のグループにデータを保存するにはどうすればよいですか。

select ProductID from CategoryProduct where CategoryID = value
4

2 に答える 2

3

Sql Server がテーブル スキャンまたはクラスター化インデックス スキャン (テーブルがクラスター化されている場合) を実行してデータをフェッチする場合、検索引数、ロック ヒント、およびその他のパラメーターのために、リーフ ページ チェーンに従うことを選択するか、インデックス割り当てマップに従うことができます。ほとんどの場合、ページ分割が発生したため、同じ順序ではありません。

クラスター化されたインデックスを使用しても速度が保証されるわけではありません。Sql サーバーは、単純な要求であっても、要求ごとに異なる方法でデータを取得する方法を計算します (Sql クエリ オプティマイザーは非常に複雑なシステムです)。

特定の順序でデータを取得する方法でもありません。特定の順序でデータを取得する唯一の方法は、クエリで ORDER BY 句を指定することです (これは ANSI 仕様です)。

パフォーマンスを向上させたい場合は、リクエストのクエリ プランを検討する必要があります。リクエストのクエリ プランを取得するにはいくつかの方法があります。最も簡単な方法は、リクエストを実行する前に、Sql Magenement Studio ツールバーの [実際のクエリ プランを含める] ボタンを選択することです。

フォローアップ: クラスター化インデックスでは、クラスターが断片化されるまで、データはクラスター定義の順序で物理的に格納されます。SELECTで特定の順序でデータを取得する唯一の方法は、インデックスを作成するのではなく、SELECT に ORDER BY 句を追加することです

于 2013-11-10T13:57:17.063 に答える
1

データの順序付けをクラスター化されたキーに依存しないでください。クラスター化されたキーの順序でディスクに格納されますが、返されるデータが任意の順序で返されることが保証されるわけではありません。データを並べ替える必要がある場合は、ORDER BY句を使用する必要があります。

クエリは、インデックスの使用に関しては問題ありません。とにかく、データの順序付けはそれを検証する方法ではありません。クエリを実行し、実行計画を確認して、インデックスが実際に使用されていることを確認する必要があります。

于 2013-11-10T11:02:34.487 に答える