web-dev-qa-db-ja.com

クラスタ化インデックスを持つテーブルは、一意の非クラスタ化インデックスによって暗黙的にソートされます

ユーザーが実行しているホストプラットフォームをキャプチャするテーブルがあります。テーブルの定義は簡単です。

_IF OBJECT_ID('[Auth].[ActivityPlatform]', 'U') IS NULL
BEGIN
    CREATE TABLE [Auth].[ActivityPlatform] (
        [ActivityPlatformId] [tinyint] IDENTITY(1,1) NOT NULL
        ,[ActivityPlatformName] [varchar](32) NOT NULL
        ,CONSTRAINT [PK_ActivityPlatform] PRIMARY KEY CLUSTERED ([ActivityPlatformId] ASC)
        ,CONSTRAINT [UQ_ActivityPlatform_ActivityPlatformName] UNIQUE NONCLUSTERED ([ActivityPlatformName] ASC)
    ) ON [Auth];
END;
GO
_

保存するデータは、ブラウザの情報を使用するJavaScriptメソッドに基づいて列挙されます(私はそれ以上は知りませんが、必要に応じて調べることができます)。

Platforms

しかし、明示的な_ORDER BY_なしで基本的なSELECTを実行すると、実行プランでは、CLUSTEREDの代わりに_UNIQUE NONCLUSTERED_インデックスを使用してソートしていることが示されますインデックス。

_SELECT * FROM [Auth].[ActivityPlatform] 
_

NonclusteredCache

_ORDER BY_を明示的に指定すると、ActivityPlatformIdで正しくソートされます。

_SELECT * FROM [Auth].[ActivityPlatform] ORDER BY [ActivityPlatformId]
_

ClusteredCache

DBCC SHOWCONTIG('[Auth].[ActivityPlatform]') WITH ALL_LEVELS, TABLERESULTSは、テーブルの断片化を示しません。

これを引き起こす可能性のある何が欠けていますか?テーブルがクラスター化インデックスに作成されていると思ったので、_ORDER BY_を指定しなくても、暗黙的に自動的に並べ替えられるはずです。 UQを選択する際のSQL Serverの設定は何ですか?テーブルの作成時に指定する必要があるものはありますか?

4
PicoDeGallo

いいえ、並べ替えは暗黙的なものではないため、信頼するべきではありません。実際、最初のツールチップでは、Ordered = False。これは、SQL Serverがソートを実装するために何もしなかったことを意味します。あなたが観察することは、それがしたこと(= /// =)がしたことであり、それが試行したことではありません行う。

信頼できるソート順を予測できるようにしたい場合は、ORDER BY。限目。あなたがしない場合にあなたが観察するかもしれないものORDER BYは興味深いかもしれませんが、一貫して動作することは信頼できません。実際、この投稿の#3を参照してください。他の誰かがインデックスを追加するだけで、クエリの出力がどのように変化するかを示しています。

UQを選択する際のSQL Serverの設定は何ですか?

UNIQUE NONCLUSTEREDインデックスにはクラスタリングキーが含まれているため、クエリをカバーしています。この場合、テーブルには2つの列しかないため、クラスター化インデックスと非クラスター化インデックスには同じデータが含まれます(並べ替えが異なるだけです)。どちらも同じサイズなので、オプティマイザはどちらかを選択できます。非クラスター化インデックスを選択することは、実装の詳細です。

これを「コイン投げ」と呼びます。

14
Aaron Bertrand