我什么时候应该使用 CompiledQuery?

发布于 2024-10-16 13:16:06 字数 871 浏览 13 评论 0原文

我有一个表:

-- 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 吗?

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

I have a table:

-- Tag

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

I have a class that will have the following methods:

IEnumerable<Tag> GetAll();
IEnumerable<Tag> GetByName();

Should I use a compiled query in this case?

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

Then my GetByName method would be:

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

Which generates a SELECT ID, Name FROM Tag and execute Where on the code. Or should I avoid CompiledQuery in this case?

Basically I want to know when I should use compiled queries. Also, on a website they are compiled only once for the entire application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

把梦留给海 2024-10-23 13:16:06

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

  • 查询将执行多次,仅因参数值而异。
  • 查询足够复杂,表达式评估和视图生成的成本“很大”(反复试验)
  • 您没有使用像 IEnumerable.Contains() 这样的 LINQ 功能,它不会使用CompiledQuery
  • 您已经简化了查询,这在可能的情况下提供了更大的性能优势。
  • 您不打算进一步组合查询结果(例如,限制或项目),这具有“反编译”它的效果。

CompiledQuery 在第一次执行查询时完成其工作。它对于第一次执行没有任何好处。与任何性能调整一样,通常要避免它,直到您确定正在修复实际的性能热点。

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

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 Update: EF 5 will do this automatically (see "Entity Framework 5: Controlling automatic query compilation") . So add "You're not using EF 5" to the above list.

许久 2024-10-23 13:16:06

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

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

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

Compiled queries save you time, which would be spent generating expression trees. If the query is used often and you'll save the compiled query, you should definitely use it. I had many cases when the query parsing took more time than the actual round trip to the database.

In your case, if you are sure that it would generate SELECT ID, Name FROM Tag without the WHERE case (which I doubt, as your AllQueries function should return IQueryable and the actual query should be made only after calling ToList) - you shouldn't use it.

As someone already mentioned, on bigger tables SELECT * FROM [someBigTable] would take very long and you'll spend even more time filtering that on the client side. So you should make sure that your filtering is made on the database side, no matter if you are using compiled queries or not.

后来的我们 2024-10-23 13:16:06

编译查询对于具有大型表达式树的 linq 查询更有帮助,在重用查询时,复杂查询比一次又一次构建表达式树更能获得性能。就你而言,我想这会节省很少的时间。

compiled queries are more helpfull with linq queries with large expression trees say complex queries to gain performance over building expression tree again and again while reusing query. in your case i guess it will save a very little time.

囚你心 2024-10-23 13:16:06

编译查询是在编译应用程序时编译的,每次您经常重用查询或查询很复杂时,您一定应该尝试编译查询以使执行速度更快。

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

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

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.

慈悲佛祖 2024-10-23 13:16:06

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文