【问题标题】:Entity Framework with MySQL: ToList() very slow [duplicate]带有 MySQL 的实体框架:ToList() 非常慢 [重复]
【发布时间】:2020-05-27 13:09:02
【问题描述】:

我正在将我的 Java 应用程序移植到 C# 并发现 Entity Framework 在实例化对象时似乎真的很慢。

首先,关于正在使用的版本的一些细节:

  • VS 2019
  • .NET Framework 4.7.2
  • EF 6
  • MySQL 8.0.20

由于我要移植我的应用程序,因此我使用了 DB First 方法。

现在,我有一个包含大约 2000 个条目的表,完全独立,没有什么特别之处。在 Java 中,我手动读取表格并实例化类,这需要大约 30 毫秒 - 仍然非常慢,但足够好。在 EF 中,这需要一秒钟...

有问题的行是:

// _baat2db is my DBContext
_baatc2db.dbexchanges.ToList();

这条线总是需要一秒钟才能完成。

Using Interceptors,我记录了生成的SQL:

SELECT
`Extent1`.`exchangeId`, 
`Extent1`.`mic`, 
`Extent1`.`country`, 
`Extent1`.`city`, 
`Extent1`.`timeZoneId`, 
`Extent1`.`countryIsoCode`, 
`Extent1`.`operatingMic`, 
`Extent1`.`institution`, 
`Extent1`.`acronym`, 
`Extent1`.`website`, 
`Extent1`.`statusDate`, 
`Extent1`.`creationDate`, 
`Extent1`.`comment`, 
`Extent1`.`isOperating`, 
`Extent1`.`isActive`, 
`Extent1`.`calendarId`
FROM `dbexchange` AS `Extent1`
-- Executing at 27.05.2020 14:16:42 +02:00
-- Completed in 3 ms with result: EFMySqlDataReader

所以读取表格数据需要 3ms,这是人们所期望的。这也让我得出结论,花费这么长时间的东西与数据库或数据库连接无关,而是在处理返回的数据的过程中,可能是在实例化对象时。

表字段及其映射为INT -> intVARCHAR -> stringBIT -> bool。一个是Nullable,两个具有在生成的构造函数中设置的默认值。

有什么想法吗?有什么我应该看的吗?我该怎么做才能进一步调试问题?

谢谢!


更新:

作为D Stanley suggested,在第二次调用(20-25ms)时表现良好。

仍然很难理解为什么第一次需要 1 秒的时间,因为我之前打开了连接。例如。以下测试:

_baatc2db.Database.Connection.Open();

// now, after after StateChange to ConnectionState.Open:

Thread.Sleep(5000);
_baatc2db.dbexchanges.ToList(); // 1+ second

Thread.Sleep(5000);
_baatc2db.dbexchanges.ToList(); // 20-25ms

【问题讨论】:

  • 每次都需要一秒钟吗?通常,像这样的流程会产生巨大的启动成本(建立连接等),这可能会导致单次运行的结果出现偏差。e 如果您循环并创建列表 10 次会怎样?
  • @DStanley 非常好!是的,它第二次按预期运行(20 毫秒)!。这仍然有点难以理解(1 秒真的很长),因为即使我在 5 秒前执行Thread.Sleep 以确保程序中的其他所有内容都处于空闲状态,它也需要超过 1 秒。我之前也手动打开了连接,所以在这个测试中,连接也已经持续了 5 秒。
  • 最好使用 .NET Core 和 EF Core,因为 .NET Framework 已弃用且 EF 6 不再维护。
  • 它可能不仅仅是连接 - 它可能是 EF 类中的其他设置(构建元数据等)。
  • @IanKemp 谢谢!是的,这些步骤确实有帮助,因此回答了我的问题。首先,EFInteractiveViews 缓存将加载时间减少到 500 毫秒,然后using ngen to precompile Entity Framework 将加载时间减少到 90 毫秒左右。

标签: c# .net entity-framework-6


【解决方案1】:

正如 D Stanley 所建议的,它在第二次调用时表现良好(20-25ms)。仍然很难理解为什么 [...]

您正在将此与 Java 进行比较,所以我假设您有使用它的经验。

与 C# 最大的不同在于,在运行时它实际上将代码编译为本机代码,这是一个非常重要的步骤。并且 EF 在其之上添加了额外的代码块,因为它编译您发送到 ILASM 的表达式,然后编译为本机代码,这是双倍的昂贵。

好处是,一旦编译完成,它的运行速度将与本机代码一样快——事实上甚至更好,因为 JIT 可以利用运行它的机器来发出其他机器可能不支持的汇编指令 ( AVX、SSE 等)。

【讨论】:

    猜你喜欢
    • 2023-02-26
    • 1970-01-01
    • 2012-03-04
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2014-12-31
    • 2023-03-19
    相关资源
    最近更新 更多