1

私は、データベースのさまざまなテーブルに保存する必要がある複数のソースからデータを受け取るプロジェクトに取り組んでいます。

速い。

私はさまざまな方法で遊んできましたが、これまでに見つけた最速の方法は、TableValue パラメーターのコレクションを使用してそれらを埋め、対応するストアド プロシージャのコレクションを介して定期的にデータベースに送信することです。

結果はかなり満足です。ただし、ディスク使用率 (Perfmon の % Idle Time) を見ると、ディスクが定期的に「スラッシング」されていることがわかります (13 ~ 18 秒ごとに 0% まで「急上昇」します)。約90%。「バッチ」サイズを変えてみましたが、大きな影響はありません。

  1. 全体的なアイドル時間を減らしながら、(何らかの方法で) スパイクを回避することで、スループットを向上させることができますか?
  2. スパイクが発生している場所を特定するために注意すべき点は何ですか? (データベースは簡易復旧モードであり、事前に「大きい」サイズに設定されているため、ログ ファイルは大きくなりません)
  3. おまけ:データベースへのデータの「ストリーミング」に関する他の質問を見てきましたが、これにはStream別のデータベースからのデータが含まれているようです(最後のセクションはこちら)。そこにデータを「プッシュ」する方法はありますか?

ここに画像の説明を入力

4

3 に答える 3

1

alzaimar's answerで参照されているコードに基づいて、IObservable で動作する概念実証を行いました (できるかどうかを確認するためだけに)。それはうまくいくようです。これが実際に私がすでに持っているものよりも速いかどうかを確認するために、いくつかのきちんとしたコードをまとめる必要があります。

(次のコードは、前述の記事のコード ダウンロードのテスト プログラムのコンテキストでのみ意味を成します。)

警告: NSFW、コピー/貼り付けは自己責任で!

private static void InsertDataUsingObservableBulkCopy(IEnumerable<Person> people, 
                                                      SqlConnection connection)
{
    var sub = new Subject<Person>();

    var bulkCopy = new SqlBulkCopy(connection);
    bulkCopy.DestinationTableName = "Person";
    bulkCopy.ColumnMappings.Add("Name", "Name");
    bulkCopy.ColumnMappings.Add("DateOfBirth", "DateOfBirth");

    using(var dataReader = new ObjectDataReader<Person>(people))
    {
        var task = Task.Factory.StartNew(() =>
        {
            bulkCopy.WriteToServer(dataReader);
        });
        var stopwatch = Stopwatch.StartNew();
        foreach(var person in people) sub.OnNext(person);
        sub.OnCompleted();
        task.Wait();
        Console.WriteLine("Observable Bulk copy: {0}ms",
                           stopwatch.ElapsedMilliseconds);
    }
}
于 2013-10-10T06:17:18.967 に答える