Quindi ho un semplice processo di inserimento in blocco per prendere i dati dalla nostra tabella di gestione temporanea e spostarli nel nostro datamart.
Il processo è un semplice flusso di dati con impostazioni predefinite per "Righe per batch" e le opzioni sono "tablock" e "nessun vincolo di controllo".
Il tavolo è abbastanza grande. 587.162.986 con una dimensione dati di 201 GB e 49 GB di spazio indice. L'indice cluster per la tabella è.
CREATE CLUSTERED INDEX ImageData ON dbo.ImageData
(
DOC_ID ASC,
ACCT_NUM ASC,
MasterID ASC
)
E la chiave primaria è:
ALTER TABLE dbo.ImageData
ADD CONSTRAINT ImageData
PRIMARY KEY NONCLUSTERED
(
ImageID ASC,
DT_CRTE_DOC ASC
)
Ora abbiamo riscontrato un problema per cui BULK INSERT
tramite SSIS è incredibilmente lento. 1 ora per inserire un milione di righe. La query che popola la tabella è già ordinata e l'esecuzione della query richiede meno di un minuto.
Quando il processo è in esecuzione, vedo la query in attesa sull'inserto BULK che impiega da 5 a 20 secondi e mostra un tipo di attesa di PAGEIOLATCH_EX
. Il processo è in grado solo di INSERT
circa mille righe alla volta.
Ieri durante il test di questo processo con il mio ambiente UAT stavo riscontrando lo stesso problema. Stavo eseguendo il processo alcune volte e tentando di determinare qual è la causa principale di questo inserimento lento. Poi all'improvviso ha iniziato a funzionare in meno di 5 minuti. Quindi l'ho eseguito alcune altre volte con lo stesso risultato. Inoltre, il numero di inserti di massa in attesa di 5 secondi o più è sceso da centinaia a circa 4.
Ora questo è sconcertante perché non è che abbiamo avuto un enorme calo di attività.
La CPU durante la durata è bassa.
I tempi in cui è più lento sembrano esserci meno attese sul disco.
La latenza del disco in realtà aumenta durante l'intervallo di tempo in cui il processo è stato eseguito in meno di 5 minuti.
E l'IO era molto più basso durante i periodi in cui questo processo funziona male.
Ho già controllato e non vi è stata alcuna crescita dei file in quanto i file sono pieni solo del 70%. Il file di registro deve ancora andare al 50%. Il DB è in modalità di recupero semplice. DB ha solo un gruppo di file ma è distribuito su 4 file.
Quindi cosa mi chiedo A: perché ho visto tempi di attesa così grandi su quegli inserti di massa. B: che tipo di magia è accaduta che l'ha fatta correre più veloce?
Nota a margine. Oggi funziona di nuovo come una merda.
AGGIORNAMENTO è attualmente partizionato. Tuttavia è fatto in un metodo che è nella migliore delle ipotesi stupido.
CREATE PARTITION SCHEME [ps_Image] AS PARTITION [pf_Image]
TO ([FG_Image], [FG_Image], [FG_Image], [FG_Image])
CREATE PARTITION FUNCTION [pf_Image](datetime) AS
RANGE RIGHT FOR VALUES (
N'2011-12-01T00:00:00.000'
, N'2013-04-01T00:00:00.000'
, N'2013-07-01T00:00:00.000'
);
Questo lascia essenzialmente tutti i dati nella quarta partizione. Tuttavia, poiché tutto va nello stesso gruppo di file. I dati sono attualmente suddivisi in modo abbastanza uniforme tra questi file.
AGGIORNAMENTO 2 Queste sono le attese complessive quando il processo funziona male.
Queste sono le attese durante il periodo in cui sono stato in grado di eseguire il processo sta funzionando bene.
Il sottosistema di archiviazione è RAID collegato localmente, nessuna SAN coinvolta. I registri si trovano su un'unità diversa. Raid Controller è PERC H800 con dimensioni della cache di 1 GB. (Per UAT) Prod è un PERC (810).
Stiamo utilizzando un semplice ripristino senza backup. Viene ripristinato da una copia di produzione ogni sera.
Abbiamo anche impostato IsSorted property = TRUE
in SSIS poiché i dati sono già ordinati.
PAGEIOLATCH_EX
e ASYNC_IO_COMPLETION
stanno indicando che sta impiegando un po 'a recuperare i dati dal disco in memoria. Questo può essere un indicatore di un problema con il sottosistema del disco o potrebbe essere contesa di memoria. Quanta memoria ha disponibile SQL Server?
ASYNC_NETWORK_IO
significa che SQL Server era in attesa di inviare righe a un client da qualche parte. Suppongo che mostri l'attività delle righe che consumano SSIS dalla tabella di gestione temporanea.