我们正在使用EF 6.0,.NET 4.5并使用代码优先方法,我们的数据库有大约170个实体(表),主表包含大约150,000条记录 在第一次加载实体框架时,它需要大约25秒。 我试图改善这个时间,因为这太慢了,随着记录数量的增加,它变得越来越慢。 我尝试过生成原生图像,尝试使用预先生成的交互式视图,但我无法取得任何重大改进。
有人可以帮我吗?
感谢。
答案 0 :(得分:1)
您可以考虑实体框架预生成的映射视图。您可以使用 EF Power Tools 创建预生成视图。
使用预生成的视图可以降低模型生成视图的成本 加载(运行时)到编译时。虽然这改善了启动 在运行时的性能,你仍然会经历视图的痛苦 你正在发展的那一代。还有几个 这些技巧可以帮助降低视图生成的成本 编译时间和运行时间。
您可以参考此内容了解更多相关信息:Entity Framework Pre-Generated Mapping Views
您可以在实体框架中使用缓存来提高应用的效果。
有三种类型的缓存。
<强> 1。对象缓存 - ObjectConManager内置的ObjectStateManager 实例在内存中跟踪已经存在的对象 使用该实例检索。这也称为第一级 高速缓存中。
<强> 2。查询计划缓存 - 在a时重用生成的store命令 查询执行多次。
第3。元数据缓存 - 跨不同的模型共享模型的元数据 与同一模型的连接。
您可以参阅此文章以了解有关它的更多信息:Performance Considerations for EF 6
答案 1 :(得分:1)
我最近有一个简单的查询,它在SSMS中运行速度非常快,在我的C#程序中使用实体框架运行的时间太长了。
在解决EF性能问题时,此页面非常有用:
..但在这种情况下,没有任何帮助。所以最后,我这样做了:
List<UpcPrintingProductModel> products = new List<UpcPrintingProductModel>();
var sql = "select top 75 number, desc1, upccode "
+ "from MailOrderManager..STOCK s "
+ "where s.number like @puid + '%' "
;
var connstring = ConfigurationManager.ConnectionStrings["MailOrderManagerContext"].ToString();
using (var connection = new SqlConnection(connstring))
using (var command = new SqlCommand(sql, connection)) {
connection.Open();
command.Parameters.AddWithValue("@puid", productNumber);
using (SqlDataReader reader = command.ExecuteReader()) {
while (reader.Read()) {
var product = new UpcPrintingProductModel() {
ProductNumber = Convert.ToString(reader["number"]),
Description = Convert.ToString(reader["desc1"]),
Upc = Convert.ToString(reader["upccode"])
};
products.Add(product);
}
}
}
(对于这个特定的查询,我只是完全绕过了EF,并使用了旧的备用:System.Data.SqlClient。)
你可以厌恶地皱起鼻子;我当然做到了 - 但实际上并没有那么长的时间来写,而且它几乎立即执行。
答案 2 :(得分:0)
您还可以在应用程序启动时异步“加热” dbcontexts 来解决此问题。
protected void Application_Start()
{
// your code.
// Warming up.
Start(() =>
{
using (var dbContext = new SomeDbContext())
{
// Any request to db in current dbContext.
var response1 = dbContext.Addresses.Count();
}
});
}
private void Start(Action a)
{
a.BeginInvoke(null, null);
}
我还建议使用以下设置:(如果它们适合您的应用)
dbContext.Configuration.AutoDetectChangesEnabled = false; dbContext.Configuration.LazyLoadingEnabled = false; dbContext.Configuration.ProxyCreationEnabled = false;
跳过验证部分(即Database.SetInitializer<SomeDbContext>(null);
)
在GET查询中使用 .asNoTraking()。
有关其他信息,请参阅:
答案 3 :(得分:0)
在某些情况下,EF不使用查询计划缓存。例如,如果您使用contans,任何,所有方法或在查询中使用常量。您可以尝试NihFix.EfQueryCacheOptimizer。它将转换允许EF使用cahce的查询表达式。