我可以在实体框架中避免复杂类型的性能问题吗?

本文关键字:类型 性能 问题 复杂 实体 框架 我可以 | 更新日期: 2023-09-27 18:13:51

我有一个复杂的类型

[ComplexType]
public class mm 
{ 
    public Guid g { get; set; }
}

和继承层次

public abstract class base1
{
    public Guid id { get; set; }
    public String name { get; set; }
    public mm mm1 { get; set; }
}

和各种派生类:

public class derived1 : base1
{
    public mm derived1mm1 { get; set; }
}

派生类中有多个mm实例,因此在大约10个派生类的层次结构中,总共有大约100个mm字段。生成的数据库模式是正确的,看起来大致如下:表base1列id (guid)列名(字符串)列mm1_g (guid)列派生1mm1_g (guid)列派生1mm2_g (guid)列派生2mm1_g (guid)…

在启动时,EF中的第一个查询(预热的那个)需要几十秒。

如果我用与之对应的单独字段替换mm复杂类型,那么结果类看起来像这样:公共抽象类base1{公共Guid id{获取;设置;}公共字符串名称{获取;设置;}Public guid mm1 {get;设置;}}

和各种派生类:

public class derived1 : base1
{
    public guid derived1mm1 { get; set; }
}

,启动时间小于1秒。唯一的区别是我把复杂类型扁平化了,如果复杂类型有多个字段和自己的行为,这不是一个好的答案。

需要说明的是,这种性能下降只发生在第一次查询时,即使数据库中完全没有数据也会发生。

mm是一个复杂类型,它本身不是一个实体,也没有为它创建表,所以没有涉及到连接或其他任何东西。

这听起来像是EF6模型生成实现中的某种bug,其中涉及大量复杂类型字段。

有没有人有一个解决方案,将允许我保留复杂的类型。这是已知的bug吗?

我可以在实体框架中避免复杂类型的性能问题吗?

我最近在一个电子商务应用程序上做了一些实体性能改进。

我们学到的一些东西,可能对你有帮助

  • 尽可能晚地使用。include (mm => mm.derivedmm),就在执行调用之前(例如。tolist ())
  • 问问你自己,如果你一次需要所有的数据。如果你不需要数据,最好只是加载id列表。(延迟加载)
  • 运行SQL分析器并查看正在执行的SQL实体。有时候简单地重新排序你的Linq查询真的可以优化它生成的脚本。
  • 将数据放入ASP中。. NET缓存一旦加载。我们把成堆的数据放在内存缓存中,性能提升令人难以置信。你的数据库是瓶颈,从内存访问数据要快1000倍。