23

我有一张桌子:

-- 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 TagWhere在代码上执行。还是CompiledQuery在这种情况下我应该避免?

基本上我想知道什么时候应该使用编译查询。此外,在网站上,它们只为整个应用程序编译一次?

4

5 回答 5

33

You should use a CompiledQuery when all of the following are true:

  • The query will be executed more than once, varying only by parameter values.
  • The query is complex enough that the cost of expression evaluation and view generation is "significant" (trial and error)
  • You are not using a LINQ feature like IEnumerable<T>.Contains() which won't work with CompiledQuery.
  • You have already simplified the query, which gives a bigger performance benefit, when possible.
  • You do not intend to further compose the query results (e.g., restrict or project), which has the effect of "decompiling" it.

CompiledQuery does its work the first time a query is executed. It gives no benefit for the first execution. Like any performance tuning, generally avoid it until you're sure you're fixing an actual performance hotspot.

2012 更新: EF 5 将自动执行此操作(请参阅“实体框架 5:控制自动查询编译”)。因此,将“您没有使用 EF 5”添加到上面的列表中。

于 2011-02-08T17:34:05.880 回答
6

编译后的查询可以节省您用于生成表达式树的时间。如果查询经常使用并且您将保存已编译的查询,那么您绝对应该使用它。在很多情况下,查询解析所花费的时间比数据库的实际往返时间要长。

在您的情况下,如果您确定它会在SELECT ID, Name FROM Tag没有WHERE大小写的情况下生成(我怀疑,因为您的AllQueries函数应该返回IQueryable并且实际查询应该只在调用之后进行ToList) - 您不应该使用它。

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

于 2011-02-08T12:38:49.760 回答
1

编译的查询对于具有大型表达式树的 linq 查询更有帮助,例如复杂查询在重用查询时一次又一次地构建表达式树以获得性能。在你的情况下,我想它会节省很少的时间。

于 2011-02-08T11:56:17.393 回答
1

Compiled queries are compiled when the application is compiled and every time you reuse a query often or it is complex you should definitely try compiled queries to make execution faster.

But I would not go for it on all queries as it is a little more code to write and for simple queries it might not be worthwhile.

But for maximum performance you should also evaluate Stored Procedures where you do all the processing on the database server, even if Linq tries to push as much of the work to the db as possible you will have situations where a stored procedure will be faster.

于 2011-02-08T12:14:07.020 回答
0

Compiled queries offer a performance improvement, but it's not huge. If you have complex queries, I'd rather go with a stored procedure or a view, if possible; letting the database do it's thing might be a better approach.

于 2011-02-08T12:10:41.617 回答