c# - 带有 MySQL 的实体框架:ToList() 非常慢
问题描述
我将我的 Java 应用程序移植到 C# 并发现实体框架在实例化对象时似乎真的很慢。
首先,关于正在使用的版本的一些细节:
- VS 2019
- .NET 框架 4.7.2
- 英孚 6
- MySQL 8.0.20
由于我正在移植我的应用程序,因此我使用了 DB First 方法。
现在,我有一个包含大约 2000 个条目的表,完全独立,没有什么特别之处。在 Java 中,我手动读取表格并实例化类,这需要大约 30 毫秒 - 仍然非常慢,但足够好。在 EF 中,这需要一秒钟...
有问题的行是:
// _baat2db is my DBContext
_baatc2db.dbexchanges.ToList();
这条线总是需要一秒钟才能完成。
使用 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 -> int
和。一个是,两个具有在生成的构造函数中设置的默认值。VARCHAR -> string
BIT -> bool
Nullable
有什么想法吗?有什么我应该看的吗?我该怎么做才能进一步调试问题?
谢谢!
更新:
正如D Stanley 所建议的那样,它在第二次调用时表现良好(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
解决方案
正如 D Stanley 建议的那样,它在第二次调用时表现良好(20-25ms)。仍然很难理解为什么 [...]
您正在将此与 Java 进行比较,所以我假设您有使用它的经验。
与 C# 的最大区别在于,它在运行时实际上将代码编译为本机代码,这是一个非常重要的步骤。并且 EF 在其之上添加了额外的代码块,因为它编译您发送到 ILASM 的表达式,然后编译为本机代码,这是双倍昂贵的。
好处是,一旦编译完成,它的运行速度将与本机代码一样快——事实上甚至更好,因为 JIT 可以利用运行它的机器来发出其他机器可能不支持的汇编指令(AVX、SSE , ETC)。
推荐阅读
- jquery - fadeIn 元素单击然后显示另一个元素
- vue.js - 如何根据开发或生产模式更改 CSS 模块输出?
- excel - 字符串中的通配符搜索
- asp.net-web-api2 - C#如何自动化需要过期的sessionId的api请求
- azure - 为多个订阅创建 Azure 服务主体
- r - SQLite 和 Shiny/flexdashboard:无法在 SQL 查询中嵌入 reactiveValues() 对象
- linux - 什么是混淆 grep 和 ack?
- css - 我可以在响应式导航栏中使用“置顶”吗?
- python - Discord 机器人没有响应
- postgresql - 为什么这会导致“org.postgresql.util.PSQLException:列索引超出范围”异常?