74

この記事を読んだ後、私は Dapper の使用方法を詳しく調べることにしました。

このコードを空のデータベースで実行しました

var members = new List<Member>();
for (int i = 0; i < 50000; i++)
{
    members.Add(new Member()
    {
        Username = i.toString(),
        IsActive = true
    });
}

using (var scope = new TransactionScope())
{
    connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);

    scope.Complete();
}

約20秒かかりました。これは 2500 回の挿入/秒です。ブログが毎秒 45,000 の挿入を達成していたことを考えると、悪くはありませんが、素晴らしいとも言えません。Dapperでこれを行うより効率的な方法はありますか?

また、補足として、このコードを Visual Studio デバッガーで実行すると 3 分以上かかりました。デバッガーが少し遅くなるだろうと思っていましたが、それを見て本当に驚きました。

アップデート

したがって、この

using (var scope = new TransactionScope())
{
    connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);

    scope.Complete();
}

この

    connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);

どちらも20秒かかりました。

しかし、これには4秒かかりました!

SqlTransaction trans = connection.BeginTransaction();

connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members, transaction: trans);

trans.Commit();
4

6 に答える 6

84

このアプローチを使用して達成できた最高の記録は、4 秒で 50,000 レコードでした

SqlTransaction trans = connection.BeginTransaction();

connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members, transaction: trans);

trans.Commit();
于 2012-09-26T19:56:45.890 に答える
14

私は最近これに出くわし、接続が開かれた後に TransactionScope が作成されることに気付きました (クエリとは異なり、Dappers Execute は接続を開かないため、これを想定しています)。こちらの回答 Q4 によると: https://stackoverflow.com/a/2886326/455904では、接続が TransactionScope によって処理されることはありません。私の同僚はいくつかの簡単なテストを行いましたが、TransactionScope の外部で接続を開くと、パフォーマンスが大幅に低下しました。

したがって、次のように変更すると機能するはずです。

// Assuming the connection isn't already open
using (var scope = new TransactionScope())
{
    connection.Open();
    connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);

    scope.Complete();
}
于 2014-01-31T15:16:26.667 に答える
0

これらの例はすべて不完全であることがわかりました。

このスレッドのより最近のより良い回答に基づいて、使用後に接続を適切に閉じ、トランザクションスコープを正しく使用して Excecute のパフォーマンスを向上させるコードを次に示します。

using (var scope = new TransactionScope()) 
{
    Connection.Open();
    Connection.Execute(sqlQuery, parameters);

    scope.Complete();
}
于 2015-07-09T08:16:19.383 に答える