SQL Server 2005
Ich muss in der Lage sein, ungefähr 350 Millionen Datensätze in einer 900 Millionen Datensatztabelle kontinuierlich zu verarbeiten. Die Abfrage, mit der ich die zu verarbeitenden Datensätze auswähle, wird während der Verarbeitung stark fragmentiert, und ich muss die Verarbeitung stoppen, um den Index neu zu erstellen. Pseudodatenmodell & Abfrage ...
/**************************************/
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;
/**************************************/
Dateninhalt ...
Während die Spalte [Datentyp] als CHAR (1) eingegeben wird, entsprechen ungefähr 35% aller Datensätze 'X', während der Rest 'A' entspricht.
Von nur den Datensätzen, bei denen [DataType] gleich 'X' ist, haben etwa 10% den Wert NOT NULL [DataStatus].
Die Spalten [ProcessDate] und [ProcessThreadId] werden für jeden verarbeiteten Datensatz aktualisiert.
Die Spalte [Datentyp] wird in etwa 10% der Fälle aktualisiert ('X' wird in 'A' geändert).
Die Spalte [DataStatus] wird in weniger als 1% der Fälle aktualisiert.
Im Moment besteht meine Lösung darin, den Primärschlüssel aller zu verarbeitenden Datensätze in einer separaten Verarbeitungstabelle auszuwählen. Ich lösche die Schlüssel, während ich sie verarbeite, so dass ich als Indexfragmente weniger Datensätze habe.
Dies passt jedoch nicht zu dem Workflow, den ich haben möchte, sodass diese Daten kontinuierlich verarbeitet werden, ohne manuelle Eingriffe und erhebliche Ausfallzeiten. Ich rechne vierteljährlich mit Ausfallzeiten für die Hausarbeit. Aber jetzt, ohne die separate Verarbeitungstabelle, kann ich nicht einmal die Hälfte des Datensatzes verarbeiten, ohne dass die Fragmentierung so schlecht wird, dass der Index gestoppt und neu erstellt werden muss.
Empfehlungen für die Indizierung oder ein anderes Datenmodell? Gibt es ein Muster, das ich erforschen muss?
Ich habe die volle Kontrolle über das Datenmodell und die Prozesssoftware, sodass nichts vom Tisch ist.