EF Coreのパフォーマンス最適化のいくつかのヒント、プログラムをより速くする

EF Coreのパフォーマンス最適化のいくつかのヒント、プログラムをより速くする

いくつかの提案

最終更新 2022/05/04 15:41
清和时光
読了目安 2 分
カテゴリ
EF Core
タグ
.NET C# EF Core パフォーマンス最適化 ORM

1. EF.Functions.xxx を使用したクエリ

1.1 EF.Functions.Like を使用した曖昧検索は、StartsWithContainsEndsWith メソッドで生成される SQL 文よりもパフォーマンスが優れています。

  1. Contains 文で生成される SQL:
var data3 = dbContext.T_UserInfor.Where(u => u.userName.Contains("p")).ToList();

使用されるのは charindex です。

  1. EF.Functions.Like 文で生成される SQL:(Like に SQL のワイルドカードを組み合わせて使用)
var data1 = dbContext.T_UserInfor.Where(u => EF.Functions.Like(u.userName, "%p%")).ToList();
// または
var data2 = (from p in dbContext.T_UserInfor
              where EF.Functions.Like(p.userName, "%p%")
              select p).ToList();

使用されるのは Like です。

PS: 従来の .NET では、SqlMethods という別の使い方もあります。詳細: https://www.cnblogs.com/yaopengfei/p/11805980.html

1.2. さらに、EF.Functions.DateDiffDayDateDiffHourDateDiffMonth)があり、日、時間、月の間の数を求めます。

PS: EF Core では、StartsWithContainsEndsWith の曖昧検索は、それぞれ LeftCharIndexRight に解析され、Like にはなりません。一方、EF.Functions.LikeLike 文に解析されます。

詳細: https://www.cnblogs.com/tdfblog/p/entity-framework-core-like-query.html

2. Z.EntityFramework.Plus.EFCore の依存関係を追加して特殊な構文を使用する

これは無料ですが、Z.EntityFramework.Plus の一部のバッチデータ操作用パッケージは有料です。

  1. EFCore では、削除する前にまずクエリを実行する必要がありますが、最適化後は直接削除できます:
context.User.Where(t => t.Id == 100).Delete();
  1. 更新文の最適化:
context.User.Where(t => t.Id == 4).Update(t => new User() { NickName = "2224114", Phone = "1234" });

3. FirstOrDefault(t => t.id == 10) の代わりに正しく Find(id=10) を使用する

Find はキャッシュを優先的に検索します。以前に同じデータをクエリしたことがある場合に使用します。一方、FirstOrDefault は毎回データベースにクエリを実行します。id=10 のデータが変更された後でも、Find で取得されるデータは新しいデータです。

4. エンティティ追跡の無効化

データベースからデータをクエリすると、コンテキストはエンティティのスナップショットを作成し、エンティティを追跡します。SaveChanges を呼び出すと、エンティティに加えられた変更はすべてデータベースに保存されます。

しかし、エンティティを変更せずにクエリのみを行う場合(読み取り専用)、エンティティ追跡は不要です。その場合は AsNoTracking を呼び出して追跡されないデータを取得することで、クエリパフォーマンスを向上させることができます。具体的なコードは次のとおりです:

var users = db.Users.AsNoTracking().ToList();

: 複数テーブルをクエリする場合は、クエリの前に次のように設定します:

db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

これにより、すべてのテーブルクエリが非追跡状態になります。

5. クエリ結果のリストに値があるかどうかを判断する場合は、.Any() を使用し、.Count().FirstOrDefault() は極力使用しないようにします。

さらに探索

関連読書

その他の記事