简体   繁体   English

实体框架核心查询生成

[英]Entity Framework Core Query Generation

Related Topic: Entity framework performance tuning相关主题: 实体框架性能调优

Does Entity Framework Core always generate query with best performance? Entity Framework Core是否总是生成性能最佳的查询? Does any body have a Counter-Example (EF query has less performance vs raw SQL query (EF generate a SQL query that we can write it in better way using raw SQL))?是否有任何机构有反例(EF 查询的性能低于原始 SQL 查询(EF 生成 SQL 查询,我们可以使用原始 SQL 以更好的方式编写它))?

Thanks谢谢

OK, one case maybe really stands out. It is that EF always generates outer joins when Include()-ing a collection. If we have prior knowledge that parents without children don't exist (or we don't need them) there's no way to instruct EF to generate an inner join for the Include, while there may be considerable performance differences between outer (worst) and inner joins (best).

To me, this was annoying enough to make me coin an IncludeInner method, which was rejected, unfortunately (and, fair enough, I didn't submit a pull request).

From an EF perspective it makes sense to generate outer joins. After all, a query like...

context.Parents.Include(p => p.Children)

...is expected to return all parents, not only the ones with children.

So now if we're interested in only parents with children we have to revert to a query like:

context.Parents.Include(p => p.Children)
    .Where(p => p.Children.Any()

We now have an OUTER JOIN and an EXISTS predicate that both access the Children table. If performance is really critical we can't but write SQL with an inner join ourselves, or write LINQ with a join statement, not using navigation proeprties.

In EF's defense, it should be noted that query generation in general has improved immensely in EF-core, as compared to its early versions and esp. Entity Framework 6 (for .net framework). While EF6 was lamentable, I dare say that EF-core-6 is one of the best now. (Although GroupBy support remains an issue).

There are many performance tips for Efficient Querying like Tracking, no-tracking and identity resolution, split queries, indexes,有许多高效查询的性能技巧,例如跟踪、不跟踪和身份解析、拆分查询、索引、
EF is ORM (object relational mapping) that finally translated to end Db Engine To prevent the programmer from getting involved in the database language has its own overhead cost you can also use raw SQL queries with FromSqlRaw EF 是 ORM (对象关系映射),最终翻译为结束 Db Engine 为了防止程序员卷入数据库语言有其自身的开销成本,您还可以使用原始 SQL 查询与FromSqlRaw

you can learn more你可以了解更多

https://docs.microsoft.com/en-us/ef/core/performance/ https://docs.microsoft.com/en-us/ef/core/performance/

Short answer is No ,简短的回答是

Explanation解释

EFCore (short for Entity Framework Core) does not aim to generate query with better performance, EFCore only aims to generate query based on the model you have provided. EFCore(Entity Framework Core 的缩写)并不旨在生成性能更好的查询,EFCore 仅旨在基于您提供的 model 生成查询。 EFCore will create correct query based on the result you are trying to achieve. EFCore 将根据您尝试实现的结果创建正确的查询。

Queries are only generated based on the navigation properties and foreign keys involved.查询仅根据所涉及的导航属性和外键生成。

Databases mostly use index statistics to generate best query plans, that has nothing to do with if query is written using EFCore or plain SQL.数据库大多使用索引统计来生成最佳查询计划,这与查询是使用 EFCore 还是普通 SQL 编写无关。

Irrespective of the way you write queries using EFCore, SQL server will choose most efficient plan always.无论您使用 EFCore 编写查询的方式如何,SQL 服务器将始终选择最有效的计划。

Split Queries拆分查询

EFCore provides query splitting, which results in smaller datasets compared to many number of joins in single query generated by older Entity Framework. EFCore 提供查询拆分,与旧实体框架生成的单个查询中的许多连接相比,这会产生更小的数据集。

You can read about it here: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries , it definitely is faster compared to earlier Entity Framework.你可以在这里阅读: https://docs.microsoft.com/en-us/ef/core/querying/single-split-queries ,与早期的实体框架相比,它肯定更快。

We have seen query times dropping to 20ms from 2 seconds, using split queries.我们已经看到使用拆分查询的查询时间从 2 秒下降到 20 毫秒。 There are very small inconsistencies as both occur in different time, and are actually executed as many separate queries.存在非常小的不一致,因为两者都发生在不同的时间,并且实际上执行了许多单独的查询。 But for most part, it is sufficient and fast.但在大多数情况下,它是足够且快速的。 And best part is you can use .AsSingleQuery() to use single query.最好的部分是您可以使用.AsSingleQuery()来使用单个查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM