我正在尝试加快常用的查询速度。使用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();
}
}
答案 0 :(得分:7)
感谢orandov,我找到了答案here(最后)。如果对查询进行任何更改,则会丢弃预编译语句。就我而言,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();
}
答案 1 :(得分: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));
答案 2 :(得分:4)
查询始终是“编译”的,只是如果你不使用CompiledQuery
那么它将按需编译。此外,CompiledQuery
仅在第一次执行时编译(不同之处在于CompiledQuery
仅编译一次,而“常规”方式将每次编译)。对于像你这样的简单查询,编译的开销可能很小。
您有trade_tag
字段的索引吗?这将为您提供最大的性能提升。
答案 3 :(得分:0)
只需设置已编译的查询以直接返回单个Trade对象,而不是返回IQueryable。这比以前的解决方案更清晰。
// 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);
}