EFCore パフォーマンス最適化ソリューション - 最適化アップデート

バッチ処理

EF Core は、すべての更新を 1 回のラウンド トリップで自動的にバッチ処理することで、ラウンド トリップを最小限に抑えるのに役立ちます。次の状況を考えてみましょう。

var blog = context.Blogs.Single(b => b.Url == "http://someblog.microsoft.com");
blog.Url = "http://someotherblog.microsoft.com";
context.Add(new Blog { Url = "http://newblog1.microsoft.com" });
context.Add(new Blog { Url = "http://newblog2.microsoft.com" });
context.SaveChanges();

上記のアクションでは、データベースからブログをロードし、その URL を変更して、2 つの新しいブログを追加します。この変更を適用するために、2 つの SQL INSERT ステートメントと 1 つの UPDATE ステートメントがデータベースに送信されます。Blog インスタンスを追加する場合、 SaveChanges を1 つずつ送信するのではなく、これらの変更は EF Core で追跡され、呼び出されたときに 1 回の往復で実行されます。

バッチアップデート

すべての従業員に昇給を与えたいとします。EF Core でのこれの一般的な実装は次のようになります。

foreach (var employee in context.Employees)
{
  employee.Salary += 1000;
}
​
context.SaveChanges();

これは完全に有効なコードですが、パフォーマンスの観点からその動作を分析してみましょう。

  • 関連するすべての従業員をロードするためにデータベースの往復が実行されます。これにより、従業員のすべての行データが (給与データのみが必要な場合でも) クライアントに提供されることに注意してください。
  • EF Core の変更追跡は、エンティティが読み込まれるときにスナップショットを作成し、それらのスナップショットをインスタンスと比較して、どのプロパティが変更されたかを調べます。
  • データベースへの 2 回目の往復を実行して、すべての変更を保存します。バッチ処理によりすべての変更は 1 ラウンド トリップで行われますが、EF Core は各従業員に対して UPDATE ステートメントを送信し、これはデータベースによって実行される必要があります。

リレーショナル データベースはバッチ更新をサポートしているため、上記は次の単一の SQL ステートメントとして書き直すことができます。

UPDATE [Employees] SET [Salary] = [Salary] + 1000;

EF は現在、バッチ更新を実行するための API を提供していません。これらの項目が導入される前は、生の SQL を使用してパフォーマンス重視の操作を実行できました。

context.Database.ExecuteSqlRaw("UPDATE [Employees] SET [Salary] = [Salary] + 1000");

おすすめ

転載: blog.csdn.net/gcf10080353/article/details/131716361