SQL Server 2005
900Mのレコードテーブルで約350Mのレコードを継続的に処理できる必要があります。処理するレコードを選択するために使用しているクエリは、処理中に著しく断片化され、インデックスを再構築するために処理を停止する必要があります。疑似データモデルとクエリ...
/**************************************/
CREATE TABLE [Table]
(
[PrimaryKeyId] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
[ForeignKeyId] [INT] NOT NULL,
/* more columns ... */
[DataType] [CHAR](1) NOT NULL,
[DataStatus] [DATETIME] NULL,
[ProcessDate] [DATETIME] NOT NULL,
[ProcessThreadId] VARCHAR (100) NULL
);
CREATE NONCLUSTERED INDEX [Idx] ON [Table]
(
[DataType],
[DataStatus],
[ProcessDate],
[ProcessThreadId]
);
/**************************************/
/**************************************/
WITH cte AS (
SELECT TOP (@BatchSize) [PrimaryKeyId], [ProcessThreadId]
FROM [Table] WITH ( ROWLOCK, UPDLOCK, READPAST )
WHERE [DataType] = 'X'
AND [DataStatus] IS NULL
AND [ProcessDate] < DATEADD(m, -2, GETDATE()) -- older than 2 months
AND [ProcessThreadId] IS NULL
)
UPDATE cte
SET [ProcessThreadId] = @ProcessThreadId;
SELECT * FROM [Table] WITH ( NOLOCK )
WHERE [ProcessThreadId] = @ProcessThreadId;
/**************************************/
データの内容...
列[DataType]はCHAR(1)として入力されますが、すべてのレコードの約35%は「X」に等しく、残りは「A」に等しくなります。
[DataType]が 'X'に等しいレコードのみのうち、約10%がNOT NULL [DataStatus]値を持ちます。
[ProcessDate]列と[ProcessThreadId]列は、処理されるすべてのレコードに対して更新されます。
[DataType]列が約10%更新されます(「X」が「A」に変更されます)。
[DataStatus]列が更新される時間は1%未満です。
今のところ私の解決策は、すべてのレコードの主キーを選択して、別の処理テーブルに処理することです。インデックスフラグメントとして処理するレコードが少なくなるように、キーを処理するときに削除します。
ただし、これは、手動での介入や大幅なダウンタイムなしでこれらのデータが継続的に処理されるようにしたいワークフローには適合しません。ハウスキーピングの家事のために、四半期ごとにダウンタイムを予想しています。しかし今は、個別の処理テーブルがないと、断片化が悪化してインデックスを停止して再構築する必要が生じない限り、データセットの半分でも処理できません。
インデックス付けまたは別のデータモデルに関する推奨事項はありますか?調査する必要があるパターンはありますか?
私はデータモデルとプロセスソフトウェアを完全に制御できるので、何も問題はありません。