3

よく使うクエリを高速化しようとしています。使用するCompiledQueryことが答えのようでした。しかし、コンパイルされたバージョンを試したところ、コンパイルされたバージョンとコンパイルされていないバージョンのパフォーマンスに違いはありませんでした。

Queries.FindTradeByTradeTagCompiled誰かが使用するよりも速くない理由を教えてもらえますかQueries.FindTradeByTradeTag

static class Queries
{
    // Pre-compiled query, as per http://msdn.microsoft.com/en-us/library/bb896297
    private static readonly Func<MyEntities, int, IQueryable<Trade>> mCompiledFindTradeQuery =
        CompiledQuery.Compile<MyEntities, int, IQueryable<Trade>>(
            (entities, tag) => from trade in entities.TradeSet
                               where trade.trade_tag == tag
                               select trade);

    public static Trade FindTradeByTradeTagCompiled(MyEntities entities, int tag)
    {
        IQueryable<Trade> tradeQuery = mCompiledFindTradeQuery(entities, tag);

        return tradeQuery.FirstOrDefault();
    }

    public static Trade FindTradeByTradeTag(MyEntities entities, int tag)
    {
        IQueryable<Trade> tradeQuery = from trade in entities.TradeSet
                                       where trade.trade_tag == tag
                                       select trade;

        return tradeQuery.FirstOrDefault();
    }
}
4

4 に答える 4

7

orandovのおかげで、私はここで答えを見つけました(最後に)。クエリに変更を加えると、プリコンパイルさたステートメントは破棄されます。私の場合、FirstOrDefault()基になるクエリを変更していました。

AsEnumerable()解決策は、最初にクエリを呼び出すことでした。プリコンパイルされたクエリを呼び出すことによりAsEnumerable()、保護さFirstOrDefault()れ、結果に対してローカルで実行されました(Linq.Enumerable.FirstOrDefaultではなくに対して呼び出されましたLinq.Queryable.FirstOrDefault)。

最終結果:実行時間が45ミリ秒から4ミリ秒に短縮されました。11倍高速。

public static Trade FindTradeByTradeTagCompiled(MyEntities entities, int tag)
{
    IQueryable<Trade> tradeQuery = mCompiledFindTradeQuery(entities, tag);

    return tradeQuery.AsEnumerable().FirstOrDefault();
}
于 2010-04-13T00:47:18.540 に答える
5

AsEnumerable(データベースでの結果を制限することはありません)ではなく、次のことを試しましたか?

// Pre-compiled query, as per http://msdn.microsoft.com/en-us/library/bb896297
private static readonly Func<MyEntities, int, IQueryable<Trade>> mCompiledFindTradeQuery =
    CompiledQuery.Compile<MyEntities, int, IQueryable<Trade>>(
        (entities, tag) => (from trade in entities.TradeSet
                           where trade.trade_tag == tag
                           select trade).Take(1));
于 2010-04-13T03:51:28.247 に答える
4

クエリは常に「コンパイル」されます。使用しない場合は、CompiledQueryオンデマンドでコンパイルされます。また、CompiledQueryとにかく最初に実行されたときにのみコンパイルされます(違いは、aCompiledQueryは1回だけコンパイルされるのに対し、「通常の」方法は毎回コンパイルされることです)。あなたが持っているような単純なクエリの場合、コンパイルのオーバーヘッドはおそらくかなり小さいでしょう。

trade_tagフィールドにインデックスがありますか?これにより、パフォーマンスが最大に向上します。

于 2010-04-12T23:52:30.300 に答える
0

IQueryableを返す代わりに、単一のTradeオブジェクトを直接返すようにコンパイルされたクエリを設定するだけです。これは、以前のソリューションよりもはるかにクリーンなコードです。

// Pre-compiled query, as per http://msdn.microsoft.com/en-us/library/bb896297
private static readonly Func<MyEntities, int, Trade> mCompiledFindTradeQuery =
    CompiledQuery.Compile<MyEntities, int, Trade>(
        (entities, tag) => (from trade in entities.TradeSet
                           where trade.trade_tag == tag
                           select trade).FirstOrDefault() );

public static Trade FindTradeByTradeTagCompiled(MyEntities entities, int tag)
{
    return mCompiledFindTradeQuery(entities, tag);
}

別の例はここにあります: LinqからSQL、Linqにコンパイルされたパフォーマンス

于 2016-12-19T19:17:00.773 に答える