我可以在实体框架中避免复杂类型的性能问题吗?
本文关键字:类型 性能 问题 复杂 实体 框架 我可以 | 更新日期: 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倍。