SQL Server 2005 では、主キー (および主キーのみ) で使用可能なクラスター化インデックスを使用する代わりに、テーブル スキャンを実行する方が効率的であると判断されるのはなぜですか?
免責事項:主キーには、列が含まれていない非クラスター化の非一意のインデックスもあります。これは私にとって不可解であり、私たちはすでに良いオフィスの笑い声を上げています. このインデックスが問題になる場合は、誰を撃つべきかがわかります。残念ながら、これは本番サイトであり、単純に切り取ることはできませんが、必要に応じてそうする計画を立てます。
多分問題は精神的に欠陥のある逆指数ではありませんが...
FogLight PASS によると、主キーで行を削除すると、次のステートメントにより、1 時間に約 600 回、最大 1,000 万行のテーブルがスキャンされます。
DELETE FROM SomeBigTable WHERE ID = @ID
テーブル DDL:
CREATE TABLE [SomeBigTable]
(
[ID] [int] NOT NULL,
[FullTextIndexTime] [timestamp] NOT NULL,
[FullTextSearchText] [varchar] (max) NOT NULL,
CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
) -- ...
ON PRIMARY
クラスター化インデックスの制約の詳細:
ADD CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
) WITH PAD_INDEX = OFF
,STATISTICS_NORECOMPUTE = OFF
,SORT_IN_TEMPDB = OFF
,IGNORE_DUP_KEY = OFF
,ONLINE = OFF
,ALLOW_ROW_LOCKS = ON
,ALLOW_PAGE_LOCKS = ON
,FILLFACTOR = 75
ON PRIMARY
同じテーブルの一意ではない非クラスター化インデックス:
CREATE NONCLUSTERED INDEX [IX_SomeBigTable_ID] ON [SomeBigTable]
(
[ID] ASC
) WITH PAD_INDEX = OFF
,STATISTICS_NORECOMPUTE = OFF
,SORT_IN_TEMPDB = OFF
,IGNORE_DUP_KEY = OFF
,ONLINE = OFF
,ALLOW_ROW_LOCKS = ON
,ALLOW_PAGE_LOCKS = ON
,FILLFACTOR = 98
ON PRIMARY
[ID] 列には、同じ大きさのテーブルを指す外部キー制約もあります。
600 回のテーブル スキャンは、同じステートメントを使用したこのテーブルでの 1 時間あたりの合計削除操作の約 4% です。したがって、このステートメントのすべての実行でテーブル スキャンが発生するわけではありません。
言わずもがなですが、なんと言ってもパッキングしたい厄介なI/Oの数々です。