我什么时候应该使用CompiledQuery?

我有一张桌子:

-- Tag ID | Name ----------- 1 | c# 2 | linq 3 | entity-framework 

我有一个类将有以下方法:

 IEnumerable GetAll(); IEnumerable GetByName(); 

在这种情况下我应该使用编译的查询吗?

 static readonly Func<Entities, IEnumerable> AllTags = CompiledQuery.Compile<Entities, IEnumerable> ( e => e.Tags ); 

然后我的GetByName方法将是:

 IEnumerable GetByName(string name) { using (var db = new Entities()) { return AllTags(db).Where(t => t.Name.Contains(name)).ToList(); } } 

它生成一个SELECT ID, Name FROM Tag并在代码上执行Where 。 或者我应该在这种情况下避免使用CompiledQuery

基本上我想知道何时应该使用编译查询。 此外,在网站上,它们仅针对整个应用程序编译一次?

当满足以下所有条件时,您应该使用CompiledQuery

  • 查询将被执行多次,仅由参数值变化。
  • 查询足够复杂,表达式评估和视图生成的成本是“重要的”(试验和错误)
  • 您没有使用像IEnumerable.Contains()这样的LINQfunction,它不能与CompiledQuery
  • 您已经简化了查询,尽可能提供更大的性能优势。
  • 您不打算进一步撰写查询结果(例如,限制或项目),这会产生“反编译”效果。

CompiledQuery在第一次执行查询时执行其工作。 它对第一次执行没有任何好处。 与任何性能调优一样,通常在您确定要修复实际性能热点之前避免使用它。

2012更新: EF 5将自动执行此操作(请参阅“ entity framework5:控制自动查询编译 ”)。 所以在上面的列表中添加“你没有使用EF 5”。

编译的查询可以节省您的时间,这将花费在生成表达式树上。 如果经常使用查询并且您将保存已编译的查询,那么您一定要使用它。 我有很多情况,当查询解析比实际往返数据库花费更多时间。

在您的情况下,如果您确定它将生成SELECT ID, Name FROM Tag而没有WHERE情况(我怀疑,因为您的AllQueries函数应该返回IQueryable并且实际查询应该仅在调用ToList ) – 您不应该’使用它。

正如有人提到的那样,在较大的表上, SELECT * FROM [someBigTable]将花费很长时间,你将花费更多的时间在客户端过滤它。 因此,无论您是否使用已编译的查询,都应确保在数据库端进行过滤。

对于linq查询,编译查询更有帮助,大型表达式树表示复杂查询,以便在重用查询时反复构建表达式树的性能。 在你的情况下,我想它会节省很少的时间。

编译的查询可以提高性能,但并不是很大。 如果您有复杂的查询,我宁愿使用存储过程或视图,如果可能的话; 让数据库做它可能是一个更好的方法。

编译应用程序时编译编译的查询,每次经常重用查询或复杂时,您都应该尝试编译查询以加快执行速度。

但我不会在所有查询中使用它,因为它需要更多的代码来编写,对于简单的查询,它可能不值得。

但是为了获得最佳性能,您还应该评估在数据库服务器上执行所有处理的存储过程,即使Linq尝试将尽可能多的工作推送到数据库服务器,您也会遇到存储过程更快的情况。