Abbiamo già un sistema in esecuzione che gestisce tutte di connessione-stringhe (DB2, oracolo, MSServer).milioni di inserti: SqlBulkCopy timeout
Attualmente, stiamo usando ExecuteNonQuery()
per fare alcuni inserti.
Vogliamo migliorare le prestazioni, utilizzando SqlBulkCopy()
anziché ExecuteNonQuery()
. Abbiamo alcuni clienti con oltre 50 milioni di record.
Non vogliamo utilizzare SSIS, perché il nostro sistema supporta più database.
Ho creato un progetto di esempio per testare le prestazioni di SqlBulkCopy()
. Ho creato una semplice lettura e inserire funzioni per MSServer
Ecco la piccola funzione:
public void insertIntoSQLServer()
{
using (SqlConnection SourceConnection = new SqlConnection(_sourceConnectionString))
{
//Open the connection to get the data from the source table
SourceConnection.Open();
using (SqlCommand command = new SqlCommand("select * from " + _sourceSchemaName + "." + _sourceTableName + ";", SourceConnection))
{
//Read from the source table
command.CommandTimeout = 2400;
SqlDataReader reader = command.ExecuteReader();
using (SqlConnection DestinationConnection = new SqlConnection(_destinationConnectionString))
{
DestinationConnection.Open();
//Clean the destination table
new SqlCommand("delete from " + _destinationSchemaName + "." + _destinationTableName + ";", DestinationConnection).ExecuteNonQuery();
using (SqlBulkCopy bc = new SqlBulkCopy(DestinationConnection))
{
bc.DestinationTableName = string.Format("[{0}].[{1}]", _destinationSchemaName, _destinationTableName);
bc.NotifyAfter = 10000;
//bc.SqlRowsCopied += bc_SqlRowsCopied;
bc.WriteToServer(reader);
}
}
}
}
}
Quando ho meno che 200 000 nel mio dummyTable la copia di massa sta lavorando bene. Ma quando sono oltre 200.000 record, ho i seguenti errori:
- Tentativo di richiamare la copia di massa su un oggetto che ha un'operazione in sospeso.
O
- L'operazione di attesa scaduta (per l'IDataReader)
ho aumentato la CommandTimeout per il lettore. Sembra che abbia risolto il problema di timeout relativo a IDataReader.
Sto facendo qualcosa di sbagliato nel codice?
Mai mai SqlBulkCopy nella tabella di destinazione. Quella cosa ha seriamente rotto il codice di blocco. Soprattutto quando si utilizza il multi-threading. Crea una tabella temporanea, inseriscila in quella, quindi copia nella tabella di destinazione. – TomTom
Non sto usando la multi-threading. Sto sempre inserendo in un tavolo vuoto. – billybob
Perché sqlbulkcopy? Sul serio. Tabelle sullo stesso database: basta dire al SERVER di copiare i dati invece di caricarli sul tuo programma solo per caricarli. Seleziona direttamente nella tabella di destinazione con una dichiarazione. – TomTom