すべての接続文字列(db2、Oracle、MSServer)を処理する実行中のシステムがすでにあります。
現在、いくつかの挿入を行うためにExecuteNonQuery()
を使用しています。
SqlBulkCopy()
の代わりにExecuteNonQuery()
を使用して、パフォーマンスを向上させたいと考えています。 5,000万件を超えるレコードを持つクライアントがいます。
システムが複数のデータベースをサポートしているため、[〜#〜] ssis [〜#〜]は使用しません。
SqlBulkCopy()
のパフォーマンスをテストするためのサンプルプロジェクトを作成しました。 MSServerの簡単な読み取りおよび挿入関数を作成しました
これが小さな関数です:
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);
}
}
}
}
}
ダミーテーブルの数が200000未満の場合、バルクコピーは正常に機能しています。しかし、200 000レコードを超えると、次のエラーが発生します。
OR
リーダーのCommandTimeoutを増やしました。 IDataReaderに関連するタイムアウトの問題が解決されたようです。
コードで何か問題がありますか?
WriteToServerを呼び出す前に、以下を追加してみてください...
bc.BatchSize = 10000;
bc.BulkCopyTimeout = 0;
デフォルトのバッチサイズまたはタイムアウトが何であるかはわかりませんが、これが問題である可能性があります。お役に立てば幸いです
また、最適なパフォーマンスを得るために、さまざまなバッチサイズで遊んでみることができます。
あなたはこれを試すことができます
bc.BatchSize = 100000; // How many Rows you want to insert at a time
bc.BulkCopyTimeout = 60; // Time in Seconds. If you want infinite waiting Time then assign 0.