Grande variazione nel tempo di inserimento di massa


13

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 INSERTtramite 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 INSERTcirca 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.

processore

I tempi in cui è più lento sembrano esserci meno attese sul disco.

Waits

La latenza del disco in realtà aumenta durante l'intervallo di tempo in cui il processo è stato eseguito in meno di 5 minuti.

Latenza

E l'IO era molto più basso durante i periodi in cui questo processo funziona male.

IO

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.

Aspetta 1

Queste sono le attese durante il periodo in cui sono stato in grado di eseguire il processo sta funzionando bene.

Wait2

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 = TRUEin SSIS poiché i dati sono già ordinati.


ASYNC_NETWORK_IOsignifica 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.
Max Vernon,

PAGEIOLATCH_EXe ASYNC_IO_COMPLETIONstanno 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?
Max Vernon,

Con il nome di una tabella di ImageData, mi incuriosisci - qual è la definizione di tabella attuale? Se stai estraendo dati LOB, potresti aver eseguito il buffering sul disco (che va a BLOBTempStoragePath che, se non definito, sarà la directory% TEMP% dell'utente in esecuzione aka unità C)
billinkc

Non è possibile pubblicare la definizione di tabella ma si tratta di informazioni di documenti fuori immagine.
Zane,

Ho il sospetto che sia un problema di elaborazione parallela. Ti consiglierei di sintonizzare il tuo MAXDOP (a partire da 1 a 4) e vedere come va tutto. D'altra parte, a scopo di test, preferirei creare un comando BCP per sostituire SSIS e vedere se c'è qualche differenza.
jyao,

Risposte:


1

Non posso indicare la causa, ma credo che il file per batch predefinito per un'operazione BULK INSERT sia "all". L'impostazione di un limite nelle righe potrebbe rendere l'operazione più digeribile: ecco perché è un'opzione. (Qui e avanti, sto guardando la documentazione "BULK INSERT" di Transact-SQL, quindi potrebbe essere molto lontana per SSIS.)

Avrà l'effetto di suddividere l'operazione in più batch di X righe, ciascuna operante come una transazione separata. Se si verifica un errore, i batch completati rimarranno impegnati nella tabella di destinazione e il batch arrestato eseguirà il rollback. Se è tollerabile in quello che stai facendo, cioè puoi rieseguirlo in un secondo momento e recuperarlo, allora, provalo.

Non è sbagliato avere una funzione di partizione che mette tutti gli inserimenti correnti in una partizione di tabella, ma non vedo quanto sia utile partizionare con le partizioni nello stesso filegroup. E l'uso del datetime è scarso, e in realtà è un po 'rotto per datetime e' YYYY-MM-DD 'senza formula CONVERT esplicita da SQL Server 2008 (SQL può trattare allegramente questo come YYYY-DD-MM: non scherzare: non farti prendere dal panico, basta cambiarlo in 'AAAAMMGG', fisso: o CONVERT (datetime, 'AAAA-MM-GGT00: 00: 00', 126), penso che sia). Ma penso che usare un proxy per il valore della data (anno come int, o anno + trimestre) su cui partizionare funzionerà meglio.

Forse è un design copiato da altrove o duplicato su più datamarts. Se questo è un vero datamart, un dump dal data warehouse per fornire ai responsabili di reparto alcuni dati con cui giocare, che non sono (da te) inviati su altrove, e probabilmente di sola lettura per quanto riguarda gli utenti di dati , quindi, mi sembra che potresti rimuovere la funzione di partizione -oppure- cambiarla per mettere esplicitamente tutti i nuovi dati nella quarta partizione, qualunque cosa accada, e nessuno se ne preoccuperebbe. (Forse dovresti controllare che non importi a nessuno.)

Sembra un progetto in cui il piano è quello di eliminare i contenuti della partizione 1 qualche volta in futuro e creare un'altra nuova partizione per ulteriori nuovi dati, ma non sembra che stia succedendo qui. Almeno non è successo dal 2013.


0

Ho visto questa stessa sporadica estrema lentezza negli inserti in grandi tabelle partizionate in occasione di me stesso. Hai provato ad aggiornare le tabelle di destinazione Statistiche e quindi a eseguirlo di nuovo? Il tempo di attesa estremo potrebbe essere dovuto a statistiche scadenti e se un aggiornamento delle statistiche è stato attivato ad un certo punto durante i test, ciò spiegherebbe l'aumento di velocità. Solo un pensiero e un test facile da verificare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.