1. ホーム
  2. .net

[解決済み] Entity Frameworkが遅すぎる。どうすればいい?[クローズド]

2023-02-20 02:11:45

質問

私は、quot;Don't optimize prematurely" のマントラに従い、Entity Frameworkを使用してWCFサービスをコード化しました。

しかし、私はパフォーマンスをプロファイリングし、Entity Frameworkはあまりにも遅いです。 (私のアプリは約1.2秒で2メッセージを処理し、私が書き直している(レガシー)アプリは同じ時間で5-6メッセージを処理します。 (レガシーアプリはDBアクセスのためにsprocsを呼び出します)。

私のプロファイリングは、Entity Frameworkがメッセージごとに時間の大部分を取っていることを指摘します。

それで、私のオプションは何でしょうか?

  • もっと良いORMがあるのでしょうか?

    (普通にオブジェクトの読み書きをサポートし、高速に処理するもの...)

  • Entity Frameworkを高速化する方法はありますか?

    ( ノート : 私がより速いというのは、最初の呼び出しではなく、長い目で見たときのことです。 (最初の呼び出しは遅いですが(メッセージに15秒)、それは問題ではありません。 私はちょうどそれがメッセージの残りのために速くなることを必要とします)。

  • 私のサービスからより多くの速度を得るのを助ける、何か謎の第3のオプション。

NOTE 私のDBの操作のほとんどは、作成と更新です。 選択と削除はほとんど行いません。

どのように解決するのですか?

Entity Frameworkで実際に発行されるSQLコマンドのプロファイリングから始める必要があります。構成 (POCO, Self-Tracking entities) に応じて、最適化の余地がたくさんあります。SQLコマンドをデバッグすることができます(デバッグモードとリリースモードの間で異なってはいけません)。 ObjectSet<T>.ToTraceString() メソッドを使用して SQL コマンドをデバッグできます。さらなる最適化が必要なクエリに遭遇した場合、達成しようとしていることに関するより多くの情報を EF に与えるために、いくつかの予測を使用することができます。

例を挙げます。

Product product = db.Products.SingleOrDefault(p => p.Id == 10);
// executes SELECT * FROM Products WHERE Id = 10

ProductDto dto = new ProductDto();
foreach (Category category in product.Categories)
// executes SELECT * FROM Categories WHERE ProductId = 10
{
    dto.Categories.Add(new CategoryDto { Name = category.Name });
}

と置き換えることができる。

var query = from p in db.Products
            where p.Id == 10
            select new
            {
                p.Name,
                Categories = from c in p.Categories select c.Name
            };
ProductDto dto = new ProductDto();
foreach (var categoryName in query.Single().Categories)
// Executes SELECT p.Id, c.Name FROM Products as p, Categories as c WHERE p.Id = 10 AND p.Id = c.ProductId
{
    dto.Categories.Add(new CategoryDto { Name = categoryName });
}

私はこれを頭の中でタイプしただけなので、これが正確にどのように実行されるかではありませんが、EFは、クエリについて知っていることすべて(この場合、カテゴリ名が必要であること)を伝えれば、実際にはいくつかの素晴らしい最適化を行っています。しかし、これはイーガーローディング(db.Products.Include("Categories"))とは異なり、プロジェクションによってロードするデータ量をさらに減らすことができるからです。