どのように変更遅いparametrized挿入し高速バコピーものからメモリ)
-
02-07-2019 - |
質問
あったかを獲このような私のコード.純2.0、MS SQL)
SqlConnection connection = new SqlConnection(@"Data Source=localhost;Initial
Catalog=DataBase;Integrated Security=True");
connection.Open();
SqlCommand cmdInsert = connection.CreateCommand();
SqlTransaction sqlTran = connection.BeginTransaction();
cmdInsert.Transaction = sqlTran;
cmdInsert.CommandText =
@"INSERT INTO MyDestinationTable" +
"(Year, Month, Day, Hour, ...) " +
"VALUES " +
"(@Year, @Month, @Day, @Hour, ...) ";
cmdInsert.Parameters.Add("@Year", SqlDbType.SmallInt);
cmdInsert.Parameters.Add("@Month", SqlDbType.TinyInt);
cmdInsert.Parameters.Add("@Day", SqlDbType.TinyInt);
// more fields here
cmdInsert.Prepare();
Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(stream);
char[] delimeter = new char[] {' '};
String[] records;
while (!reader.EndOfStream)
{
records = reader.ReadLine().Split(delimeter, StringSplitOptions.None);
cmdInsert.Parameters["@Year"].Value = Int32.Parse(records[0].Substring(0, 4));
cmdInsert.Parameters["@Month"].Value = Int32.Parse(records[0].Substring(5, 2));
cmdInsert.Parameters["@Day"].Value = Int32.Parse(records[0].Substring(8, 2));
// more here complicated stuff here
cmdInsert.ExecuteNonQuery()
}
sqlTran.Commit();
connection.Close();
と cmdInsert.ExecuteNonQuery() コメントアウトされているこのコードを実行し、以下の2秒SQL実行で1m20秒が0.5費記録。テーブルは空になる。SSISデータフローのタスクの類似の機能を約20秒
- 大量挿入 た ないオプション(下記を参照)。った派手なものの中でこのサポートいたします。
- 私の試験機は、Core2Duoの2GB RAM.
- して見たときにタスクマネージャーのCPUはuntilized.IOうもない"を活用する。
- スキーマが簡単なように地獄:一テーブルAutoInt一次指数は、以下の10の整数では、小型int、char(10).
その後の答えがここで見つけることを実行することも可能で バルクからコピーメモリ!ったのを拒否し用バルクコピー beacuseと思いますからファイル...
今使っていることで抽20秒(SSISタスク)
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("ixMyIndex", System.Type.GetType("System.Int32")));
dataTable.Columns.Add(new DataColumn("Year", System.Type.GetType("System.Int32")));
dataTable.Columns.Add(new DataColumn("Month", System.Type.GetType("System.Int32")));
dataTable.Columns.Add(new DataColumn("Day", System.Type.GetType("System.Int32")));
// ... and more to go
DataRow dataRow;
object[] objectRow = new object[dataTable.Columns.Count];
Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(stream);
char[] delimeter = new char[] { ' ' };
String[] records;
int recordCount = 0;
while (!reader.EndOfStream)
{
records = reader.ReadLine().Split(delimeter, StringSplitOptions.None);
dataRow = dataTable.NewRow();
objectRow[0] = null;
objectRow[1] = Int32.Parse(records[0].Substring(0, 4));
objectRow[2] = Int32.Parse(records[0].Substring(5, 2));
objectRow[3] = Int32.Parse(records[0].Substring(8, 2));
// my fancy stuf goes here
dataRow.ItemArray = objectRow;
dataTable.Rows.Add(dataRow);
recordCount++;
}
SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null);
bulkTask.DestinationTableName = "MyDestinationTable";
bulkTask.BatchSize = dataTable.Rows.Count;
bulkTask.WriteToServer(dataTable);
bulkTask.Close();
解決
の代わりに挿入それぞれに個々には受け付けていません SqlBulkCopy クラスからバルクに挿入し、すべてのデータです。
をDataTableに追加すべての記録のDataTable、その利用 SqlBulkCopy.WriteToServer バルクを挿入しすべてのデータです。
他のヒント
必要にします。用取引に必要な資源をより簡単なっています。
まず、挿入した値をcorectしてお使いいただけますBulkInsert.
1分の音がかなりリーズナブル0.5百万円の記録です。ことになる記録毎0.00012秒です。
はテーブルに任意指標?取り除くことで、このとreapplyingにした後、大量挿入を向上させ性能の挿入、という場合は、オプションとなっています。
ていることに対して無理なく処理8,333当たりのデータエコノミープランです。どのようなスループットを期待しますか?
が必要な場合はより良い速度で性を高めることが考えられますが実施大量挿入:
場合に何らかの形のバルクを挿入しないオプション、その他の方法も複数のスレッドがそれぞれのデータベースです。
問題は、現在のシステムは、500,000往復し、データベースに、お待ちして最初の往復の完了前に、何らかのレーテンシー(ie、ネットワークの機械うになるのに時間が待っています。
できれば分割モジュールのインストールしても利用がプロデューサー/消費者セットアップ、を感じるかもしれませんがうまく活用のすべての資源です。
しかし、これまでの紛失、あるいはひとつの大きな取引その他のライターのスレッドがブロックすべてにまで、その取引が完了します。にもそのままお使いいただけ取引ができない多く使用の小型のものよりも1大きます。
のSSISする高速での使用のバルクインフォメーションの方法-いすべての複雑な処理を最終リストのデータを挿入すいと同時に、バルクをサポートしていません。
なっているのでしょうか何が起きているのは約58秒の身体を挿入する500,000記録していただく必要があり周辺は10,000に挿入します。ることを知らずのスペックのデータベースサーバマシン(見ご利用のlocalhostでネットワーク遅延べきでない問題で困ることはないんだが良い、悪い、または最悪でした。
いていデータベースのスキーマ-がバインデックスのテーブルが更新された挿入?これからその他のテーブルは外部キーを参照を表す。がSQLプロファイリングツールのパフォーマンス-モニタリング施設へのSQLサーバー、でもそんなに使用します。その場合表示の問題のようなロックとか。
にゃんのデータは、すべての記録です。その後バルクを挿入します。
(ただいまの選択した後、挿入..あると思いますかの問題に対応する業務データの前にBulkInsert
の開始をおためしくださいね、よろしくお願いようになっていると言っても過言ではあり多くの間違った種類の指数にtbTrafficLogTTLます。なのでスキーマ定義のテーブルさんが私のと同等の性能問題の場合:
- の主キーがこの一次指数はペアをクラスタリングしました。
- が何らかの固有インデックスに設定します。
- 多数の指数です。
起動する場合は数万列データの時間を維持することを目指指数を追加します。
まもることがありますのでご注意くだいて、任意のオプションに変換する年、月、日、時、分、秒の分野を単一のdatetime2はデフォルトデータベースの分野ます。を追加した多くの複雑さへのデータアーキテクチャは、せん。理由はただそれだけかもしろい考えを利用分野ような構造であれば対応、既存のデータベースのスキーマを変更できませんするものとします。その場合すべきます。
あったかと同じような問題私の最後の契約になります。ん500,000旅行するSQLを挿入します。飛躍的な増性能についを調べるBulkInsert法のSQL名前また"再読み込み"の工程から2時間の回復のカップルダーステーブルを31秒まで実施バルにサポートいたします。
ことが可能なように、bcpのコマンドです。合う機会を設けていきたいと思い、ご提案については上のを大量挿入スケジュールでベット。ん500,000往復し、データベースに書き500,000エントリのログファイルはもちろんスペースが必要なの配分のログファイルは、テーブル、スを作成します。
だ挿入するためには、異なるクラスタ化されたインデックスものではありませんの時間を要する再編成の物理データの速度で処理が行われます。多変数がかなクエリの実行がりが遅いということです。
~10,000取引の毎秒なひどいため個別に挿入しに来roundtrippingからコード/