简体   繁体   English

EF Core 查询性能

[英]EF Core Query Performance

I have a query that loads extremely slowly.我有一个加载非常缓慢的查询。 I think something is very wrong with it, but i dont understand why.我认为它有很大的问题,但我不明白为什么。 In my application i have an entity KeyText:在我的应用程序中,我有一个实体 KeyText:

public class KeyText
    int Id
    Group Group
    string Text

Most other entities have several of these keytexts.大多数其他实体有几个这样的关键文本。 Its just a simple way of filling comboboxes.它只是填充组合框的一种简单方法。 So if i load via ef core like this: (Everything in the ThenInclude lambda is a KeyText)因此,如果我像这样通过 ef 核心加载:(ThenInclude lambda 中的所有内容都是 KeyText)

context.Companies
    .Include(c => c.Adresses).ThenInclude(a => a.AdressType);
    .Include(c => c.Adresses).ThenInclude(a => a.CityType);
    .Include(c => c.Adresses).ThenInclude(a => a.AnotherKeyText);
    .Include(c => c.Adresses).ThenInclude(a => a.DifferentKeyText);

This can, in the real app, load up to 20 seconds for a ridicolously low amount of data.在真正的应用程序中,这可以加载最多 20 秒的数据量。 I'm talking like 5 entries in 5 collections.我说的是 5 collections 中的 5 个条目。

However if i load like this:但是,如果我这样加载:

var companies = context.Companies;
companies.adresses = context.Adresses
                        Include(a => a.AdressType)
                        Include(a => a.CityType)
                        Include(a => a.AnotherKeyText)
                        Include(a => a.DifferentKeyText);

It loads instantly.它立即加载。 Why is this?为什么是这样? Is the first query that wrong?第一个查询错了吗?

Let assume you have 5 companies, each one has 5 Addresses:假设您有 5 家公司,每家公司有 5 个地址:

context.Companies
    .Include(c => c.Adresses).ThenInclude(a => a.AdressType);
    .Include(c => c.Adresses).ThenInclude(a => a.CityType);
    .Include(c => c.Adresses).ThenInclude(a => a.AnotherKeyText);
    .Include(c => c.Adresses).ThenInclude(a => a.DifferentKeyText);

This code generates 5*5=25 left join behalf of Sql each one composed of 3 join (Companies * Adresses * types)此代码生成 5*5=25 left join 代表 Sql 每一个由 3 个 join 组成(Companies * Adresses * types)


var companies = context.Companies;
companies.adresses = context.Adresses
    .Include(a => a.AdressType)
    .Include(a => a.CityType)
    .Include(a => a.AnotherKeyText)
    .Include(a => a.DifferentKeyText);

This code generates 5 left join behalf of Sql each one composed of 2 join (Adresses * types)此代码生成 5 个左连接代表 Sql 每一个由 2 个连接(地址 * 类型)组成

So it's obvious that first approach damages your performance significantly.所以很明显,第一种方法会显着损害你的表现。

Anyway try to not use Include as far as you can.无论如何尽量不要使用Include Instead load minimum amount of data that you need and with Join and Select expressions.而是使用JoinSelect表达式加载您需要的最少数据量。

Another option to speed up your query in EF is using .AsNoTracking()EF中加快查询速度的另一个选项是使用.AsNoTracking()

var companies = context.Companies.AsNoTracking();
companies.adresses = context.Adresses.AsNoTracking()
                        .Include(a => a.AdressType)
                        .Include(a => a.CityType)
                        .Include(a => a.AnotherKeyText)
                        .Include(a => a.DifferentKeyText)
context.Companies.AsNoTracking()
    .Include(c => c.Adresses).ThenInclude(a => a.AdressType);
    .Include(c => c.Adresses).ThenInclude(a => a.CityType);
    .Include(c => c.Adresses).ThenInclude(a => a.AnotherKeyText);
    .Include(c => c.Adresses).ThenInclude(a => a.DifferentKeyText);

No tracking queries are useful when the results are used in a read-only scenario.当结果用于只读方案时,没有跟踪查询很有用。 They're quicker to execute because there's no need to set up the change tracking information.它们执行速度更快,因为无需设置更改跟踪信息。 If you don't need to update the entities retrieved from the database, then a no-tracking query should be used.如果您不需要更新从数据库中检索到的实体,则应使用无跟踪查询。 You can swap an individual query to be no-tracking您可以将单个查询交换为不跟踪

By default, queries that return entity types are tracking.默认情况下,返回实体类型的查询正在跟踪。 Which means you can make changes to those entity instances and have those changes persisted by SaveChanges() .这意味着您可以对这些实体实例进行更改,并通过SaveChanges()这些更改。

When you load data from Database by default all records has been tracked by ChangeTracker and this will cause a slight drop in speed and memory allocation.默认情况下,当您从数据库加载数据时, ChangeTracker已跟踪所有记录,这将导致速度和 memory 分配略有下降。

在此处输入图像描述

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

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