LINQからEFのパフォーマンスを向上させる方法

私は2つのクラスを持っています:プロパティとPropertyValue。プロパティにはいくつかの値があり、各値は新しいリビジョンです。

プロパティのセットを取得するときに、各プロパティの値の最新のリビジョンを含めたいと思います。

T-SQLでは、これは次のように非常に効率的に行うことができます:

SELECT 
p.Id,
pv1.StringValue,
pv1.Revision
FROM dbo.PropertyValues pv1
LEFT JOIN dbo.PropertyValues pv2 ON pv1.Property_Id = pv2.Property_Id AND pv1.Revision < pv2.Revision
JOIN dbo.Properties p ON p.Id = pv1.Property_Id
WHERE pv2.Id IS NULL
ORDER BY p.Id

このクエリの「マジック」は、より小さい条件で結合し、結果がLEFT JOINによって強制されない行を探すことです。

LINQ to EFを使用して同様のことを達成するにはどうすればよいですか?

私が思いつくことができる最高のものは次のとおりでした:

from pv in context.PropertyValues
group pv by pv.Property into g
select g.OrderByDescending(p => p.Revision).FirstOrDefault()

正しい結果が得られますが、他のものより約10倍遅くなります。

4

3 答え

多分これが助けになるかもしれない。 dbはデータベースコンテキストです。

(
            from pv1 in db.PropertyValues
            from pv2 in db.PropertyValues.Where(a=>a.Property_Id==pv1.Property_Id && pv1.Revision
1
追加された
多分あなたは解決策を受け入れることができますか?
追加された 著者 Arion,
これはとてもうまく動作します!ありがとうございました!!
追加された 著者 user1104938,

Linq To Entitiesでクエリを最適化した後、Entity FrameworkがクエリをSQLに変換して結果をオブジェクトに戻すために必要な作業にも注意する必要があります。

Linq To EntitiesクエリをSQLクエリと直接比較すると、Entity Frameworkがより多くの作業を行うため、パフォーマンスが低下します。

したがって、Entity Frameworkの手順を最適化することも検討することが重要です。

助けることができるもの:

  • クエリをプリコンパイルする
  • ビューを事前生成する
  • データベース接続を開くタイミングを自分で決める
  • トラッキングを無効にする(該当する場合)

Here you can find some documentation with performance strategies.

1
追加された
あなたが結果のSQLクエリを見て、あなたの手書きSQLにSQL部分の実行時間を測定するならば、それは私が思う公正であるはずです:)
追加された 著者 Wouter de Kort,
ありがとう、私はそれをSQLプロファイラを使用して比較します。それはMMSの権利と比較すると可能な限り公平にする必要がありますか?
追加された 著者 user1104938,

結合で複数の条件(式より小さい)を使用する場合は、次のようにすることができます

from pv1 in db.PropertyValues
 join pv2 in db.PropertyValues on new{pv1.Property_ID, Condition = pv1.Revision < pv2.Revision} equals new {pv2.Property_ID , Condition = true} into temp
from t in temp.DefaultIfEmpty()
            join p in db.Properties
                on pv1.Property_Id equals p.Id
            where t.Id==null
            orderby p.Id
            select new
            {
                p.Id,
                pv1.StringValue,
                pv1.Revision
            }
0
追加された
グループ化クエリは非常に遅いため、グループの各キーごとに別々に実行されるため
追加された 著者 Muhammad Adeel Zahid,
あなたは男です!私は、DefaultOrEmpty()がLEFT JOINを生成するというアイデアは持っていませんでした。それはあなたがそれについて考えるときにかなり明白です。 pv1.Property.Idやwhere t == nullのようないくつかの変更を加えなければならなかったのですが、それ以外にはその点がありました!ありがとう!
追加された 著者 user1104938,