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%。
现在,我的解决方案是选择所有记录的主键,以处理到单独的处理表中。我在处理键时将其删除,以便作为索引碎片处理更少的记录。
但是,这不适合我想要的工作流程,因此这些数据可以连续处理,而无需人工干预和大量停机。我确实会每季度因为一次家务而停机。但是现在,如果没有单独的处理表,我什至无法处理一半的数据集,而碎片变得如此糟糕,以至于必须停止并重建索引。
对索引或其他数据模型有什么建议吗?我需要研究一种模式吗?
我对数据模型和过程软件拥有完全的控制权,因此没有任何问题。