0

Devart DotConnect for Oracle で POCO を使用すると、コード フラグメント 1 がコード 2 よりも高速である理由を知りたいです。

100000 レコード以上試してみましたが、コード 1 は 2 よりもずっと高速です。なぜですか? 接続が1つしかないため、「SaveChanges」はバッファをクリアして高速化すると思いました。私が間違っている?

コード 1:

        for (var i = 0; i < 100000; i++)
        {
            using (var ctx = new MyDbContext())
            {
                MyObj obj = new MyObj();
                obj.Id = i;
                obj.Name = "Foo " + i;
                ctx.MyObjects.Add(obj);
                ctx.SaveChanges();
            }
        }

コード 2:

        using (var ctx = new MyDbContext())
        {
            for (var i = 0; i < 100000; i++)
            {
                MyObj obj = new MyObj();
                obj.Id = i;
                obj.Name = "Foo " + i;
                ctx.MyObjects.Add(obj);
                ctx.SaveChanges();
            }
        }
4

1 に答える 1

3

最初のコード スニペットは、同じ接続が毎回プールから取得されるため、より高速に動作するため、再オープン時にパフォーマンスが低下することはありません。

2 番目のケースでは、100000 個のオブジェクトがコンテキストに徐々に追加されます。低速のスナップショット ベースの追跡が使用されます (動的プロキシがない場合)。これにより、各 SaveChanges() でキャッシュされたオブジェクトの変更が発生したかどうかが検出されます。後続の反復ごとに、より多くの時間が費やされます。

次のアプローチを試すことをお勧めします。上記のものよりも優れたパフォーマンスが必要です。

using (var ctx = new MyDbContext())
    {
        for (var i = 0; i < 100000; i++)
        {
            MyObj obj = new MyObj();
            obj.Id = i;
            obj.Name = "Foo " + i;
            ctx.MyObjects.Add(obj);                
        }
        ctx.SaveChanges();
    }

編集

1 つの SaveChanges() 内で多数の操作を実行するアプローチを使用する場合、Devart dotConnect for Oracle プロバイダーの Entity Framework の動作を追加で構成すると便利です。

// Turn on the Batch Updates mode:
var config = OracleEntityProviderConfig.Instance;
config.DmlOptions.BatchUpdates.Enabled = true;

// If necessary, enable the mode of re-using parameters with the same values:
config.DmlOptions.ReuseParameters = true;

// If object has a lot of nullable properties, and significant part of them are not set (i.e., nulls), omitting explicit insert of NULL-values will decrease greatly the size of generated SQL:
config.DmlOptions.InsertNullBehaviour = InsertNullBehaviour.Omit;

ここでは、いくつかのオプションのみを説明します。それらの完全なリストは、私たちの記事で入手できます: http://www.devart.com/blogs/dotconnect/index.php/new-features-of-entity-framework-support-in-dotconnect-providers.html

SaveChanges() が呼び出されると、キャッシュ内のすべてのオブジェクトが DB に格納され、キャッシュがクリアされると仮定するのは間違っているので、各ループは独立していますか?

SaveChanges() はすべての変更をデータベースに送信してコミットしますが、コンテキストに関連付けられているすべてのエンティティに対して変更追跡が継続されます。また、新しい SaveChanges は、スナップショット ベースの変更追跡が使用されている場合、各オブジェクトの各プロパティの値を確認する (変更されているかどうか) 長いプロセスを開始します。

于 2011-09-07T08:14:08.813 に答える