SQL Server 2005
Devo essere in grado di elaborare continuamente circa 350 milioni di record in una tabella di record di 900 milioni. La query che sto usando per selezionare i record da elaborare diventa fortemente frammentata mentre elaboro e ho bisogno di interrompere l'elaborazione per ricostruire l'indice. Modello di dati pseudo e query ...
/**************************************/
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;
/**************************************/
Contenuto dei dati ...
Mentre la colonna [DataType] è digitata come CHAR (1), circa il 35% di tutti i record è uguale a "X" mentre il resto è uguale a "A".
Solo dei record in cui [DataType] è uguale a 'X', circa il 10% avrà un valore NOT NULL [DataStatus].
Le colonne [ProcessDate] e [ProcessThreadId] verranno aggiornate per ogni record elaborato.
La colonna [DataType] viene aggiornata ('X' viene cambiata in 'A') circa il 10% delle volte.
La colonna [DataStatus] viene aggiornata meno dell'1% delle volte.
Per ora la mia soluzione è selezionare la chiave primaria di tutti i record da elaborare in una tabella di elaborazione separata. Elimina le chiavi mentre le elaboro in modo che, come frammenti di indice, ho a che fare con meno record.
Tuttavia, questo non si adatta al flusso di lavoro che desidero avere in modo che questi dati vengano elaborati continuamente, senza intervento manuale e significativi tempi di inattività. Prevedo i tempi di inattività su base trimestrale per le faccende domestiche. Ma ora, senza la tabella di elaborazione separata, non riesco a superare nemmeno la metà del set di dati senza che la frammentazione diventi così grave da richiedere l'interruzione e la ricostruzione dell'indice.
Qualche consiglio per l'indicizzazione o un modello di dati diverso? C'è un modello che devo ricercare?
Ho il pieno controllo del modello di dati e del software di processo, quindi nulla è fuori dal tavolo.