我有一张桌子:
-- Tag
ID | Name
-----------
1 | c#
2 | linq
3 | entity-framework
我有一个类将具有以下方法:
IEnumerable<Tag> GetAll();
IEnumerable<Tag> GetByName();
在这种情况下我应该使用编译的查询吗?
static readonly Func<Entities, IEnumerable<Tag>> AllTags =
CompiledQuery.Compile<Entities, IEnumerable<Tag>>
(
e => e.Tags
);
然后我的GetByName
方法将是:
IEnumerable<Tag> 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
吗?
基本上我想知道何时应该使用编译查询。另外,在一个网站上,它们只为整个应用程序编译一次?
答案 0 :(得分:28)
如果满足以下所有条件,则应使用CompiledQuery
:
IEnumerable<T>.Contains()
这样的LINQ功能,它不适用于CompiledQuery
。 CompiledQuery
在第一次执行查询时执行其工作。它对第一次执行没有任何好处。与任何性能调优一样,通常在您确定要修复实际性能热点之前避免它。
2012更新: EF 5会自动执行此操作(请参阅“Entity Framework 5: Controlling automatic query compilation”)。所以在上面的列表中添加“你没有使用EF 5”。
答案 1 :(得分:6)
编译的查询可以节省您的时间,这将花费在生成表达式树上。如果经常使用查询并且您将保存已编译的查询,那么您一定要使用它。我有很多情况,当查询解析比实际的数据库往返花费更多的时间。
在您的情况下,如果您确定在没有SELECT ID, Name FROM Tag
情况下生成WHERE
(我怀疑,因为您的AllQueries
函数应该返回IQueryable
并且只有在调用ToList
后才能进行实际查询 - 你不应该使用它。
正如有人已经提到的,在较大的表SELECT * FROM [someBigTable]
上花费很长时间,你会花更多的时间在客户端过滤它。因此,无论您是否使用已编译的查询,都应确保在数据库端进行过滤。
答案 2 :(得分:1)
编译查询对linq查询更有帮助,大型表达式树表示复杂查询可以在重用查询时反复构建表达式树。在你的情况下,我猜它会节省很少的时间。
答案 3 :(得分:0)
编译查询可以提高性能,但并不是很大。如果您有复杂的查询,我宁愿使用存储过程或视图,如果可能的话;让数据库做它可能是一种更好的方法。
答案 4 :(得分:0)
在编译应用程序时编译编译的查询,每次经常重用查询或复杂时,您都应该尝试编译查询以加快执行速度。
但是我不会在所有查询中使用它,因为它需要更多的代码来编写,对于简单的查询它可能不值得。
但是为了获得最佳性能,您还应该评估在数据库服务器上执行所有处理的存储过程,即使Linq尝试将尽可能多的工作推送到数据库服务器,您也会遇到存储过程将会存在的情况。更快。