为什么CompiledQuery没有提高性能?

Gra*_*ian 3 c# performance entity-framework compiled-query

我试图加快一个经常使用的查询.使用a 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Gra*_*ian 7

感谢orandov,我在这里找到了答案(最后).如果对查询进行任何更改,则会丢弃预编译语句.就我而言,FirstOrDefault()正在改变基础查询.

解决方案是首先调用AsEnumerable()查询.通过调用AsEnumerable()预编译的查询受到保护,并FirstOrDefault()在结果上本地执行(它被调用Linq.Enumerable.FirstOrDefault而不是Linq.Queryable.FirstOrDefault).

净结果:执行时间从45ms减少到4ms.快了11倍.

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

    return tradeQuery.AsEnumerable().FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 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));
Run Code Online (Sandbox Code Playgroud)