A cosa serve la dimensione del batch consigliata SqlBulkCopy
? Sto cercando una formula generale da utilizzare come punto di partenza per l'ottimizzazione delle prestazioni.
A cosa serve la dimensione del batch consigliata SqlBulkCopy
? Sto cercando una formula generale da utilizzare come punto di partenza per l'ottimizzazione delle prestazioni.
Risposte:
Ho un'utilità di importazione che si trova sullo stesso server fisico della mia istanza di SQL Server. Utilizzando un custom IDataReader
, analizza i file flat e li inserisce in un database utilizzando SQLBulkCopy
. Un file tipico ha circa 6 milioni di righe qualificate, con una media di 5 colonne di testo decimale e breve, circa 30 byte per riga.
Alla luce di questo scenario, ho riscontrato che una dimensione batch di 5.000 è il miglior compromesso tra velocità e consumo di memoria. Ho iniziato con 500 e ho sperimentato con più grandi. Ho scoperto che 5000 sono in media 2,5 volte più veloci di 500. L'inserimento di 6 milioni di righe richiede circa 30 secondi con una dimensione del batch di 5.000 e circa 80 secondi con una dimensione del batch di 500.
10.000 non erano misurabilmente più veloci. Il passaggio a 50.000 ha migliorato la velocità di alcuni punti percentuali ma non valeva la pena aumentare il carico sul server. Oltre i 50.000 non hanno mostrato miglioramenti nella velocità.
Questa non è una formula, ma è un altro punto dati da utilizzare.
Questo è un problema che ho anche esaminato per un po 'di tempo. Sto cercando di ottimizzare l'importazione di file CSV di grandi dimensioni (16+ GB, 65+ milioni di record e in crescita) in un database SQL Server 2005 utilizzando un'applicazione console C # (.Net 2.0). Come Jeremy ha già sottolineato , sarà necessario eseguire alcune regolazioni per le circostanze particolari, ma ti consiglio di avere una dimensione del lotto iniziale di 500 e di testare i valori sia sopra che sotto questo.
Ho ricevuto la raccomandazione di testare valori compresi tra 100 e 1000 per la dimensione del batch da questo post del forum MSDN ed ero scettico. Ma quando ho testato batch di dimensioni comprese tra 100 e 10.000, ho scoperto che 500 era il valore ottimale per la mia applicazione. Anche il valore 500 per SqlBulkCopy.BatchSize
è consigliato qui .
Per ottimizzare ulteriormente l'operazione SqlBulkCopy, consulta questo consiglio MSDN ; Trovo che l'utilizzo di SqlBulkCopyOptions.TableLock aiuti a ridurre i tempi di caricamento.
Come altri hanno affermato, dipende dall'ambiente in particolare dal volume delle righe e dalla latenza di rete.
Personalmente, inizierei impostando la BatchSize
proprietà su 1000 righe e vedrei come funziona. Se funziona, continuo a raddoppiare il numero di righe (ad esempio a 2000, 4000, ecc.) Finché non ottengo un timeout.
Altrimenti, se si verifica un timeout a 1000, riduco il numero di righe della metà (es. 500) finché non funziona.
In ogni caso, continuo a raddoppiare (in caso di successo) o dimezzare (se fallito) la differenza tra ciascuna delle ultime due dimensioni di lotto tentate fino a trovare un punto ottimale.
L'altro fattore da considerare è il tempo necessario per copiare un singolo batch di righe. I timeout si verificheranno se il batch di righe da copiare supera la BulkCopyTimeout
proprietà che per impostazione predefinita è di 30 secondi. Potresti provare a raddoppiare la BulkCopyTimeout
proprietà a 60 secondi. Ciò consente un periodo di tempo più lungo per la copia di un set più ampio di righe batch. Ad esempio, un batch di 50.000 righe potrebbe richiedere circa 40 secondi superando il limite di tempo di 30 secondi, quindi aumentarlo fino a 60 secondi potrebbe aiutare con le prestazioni.
Tutto dipende dalla tua implementazione.
Che tipo di velocità puoi aspettarti sulla tua rete? Lo stai usando in Forms o ASP.Net? Hai bisogno di avvisare l'utente dei progressi? Qual è la dimensione del lavoro totale?
Nella mia esperienza, l'esecuzione di copie di massa senza una dimensione batch specificata causerà problemi di timeout. Mi piace iniziare con qualcosa come 1000 record e fare alcuni aggiustamenti da lì.
avevo provato più dimensioni, nel mio caso 5000 andava bene