SQL Server 2005
Necesito poder procesar continuamente unos 350 millones de registros en una tabla de registros de 900 millones. La consulta que estoy usando para seleccionar los registros a procesar se fragmenta mucho a medida que proceso y tengo que detener el procesamiento para reconstruir el índice. Modelo de pseudodatos y consulta ...
/**************************************/
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;
/**************************************/
Contenido de datos ...
Mientras que la columna [DataType] se escribe como CHAR (1), aproximadamente el 35% de todos los registros equivalen a 'X' con el resto igual a 'A'.
De solo los registros donde [DataType] es igual a 'X', aproximadamente el 10% tendrá un valor NOT NULL [DataStatus].
Las columnas [ProcessDate] y [ProcessThreadId] se actualizarán para cada registro procesado.
La columna [DataType] se actualiza ('X' se cambia a 'A') aproximadamente el 10% del tiempo.
La columna [DataStatus] se actualiza menos del 1% del tiempo.
Por ahora, mi solución es seleccionar la clave principal de todos los registros para procesar en una tabla de procesamiento separada. Borro las claves a medida que las proceso para que, a medida que el índice se fragmente, esté lidiando con menos registros.
Sin embargo, esto no se ajusta al flujo de trabajo que quiero tener para que estos datos se procesen continuamente, sin intervención manual y tiempo de inactividad significativo. Preveo el tiempo de inactividad trimestralmente para las tareas domésticas. Pero ahora, sin la tabla de procesamiento separada, no puedo procesar ni siquiera la mitad del conjunto de datos sin que la fragmentación se vuelva tan grave que sea necesario detener y reconstruir el índice.
¿Alguna recomendación para indexar o un modelo de datos diferente? ¿Hay algún patrón que deba investigar?
Tengo el control total del modelo de datos y el software del proceso, por lo que no hay nada fuera de la mesa.