首先,有关所使用版本的一些详细信息:
现在,我有一个大约有2000个条目的表,完全是独立的,没有什么特别的。在Java中,我手动读取了表并实例化了类,这花费了大约30ms的时间-仍然非常慢,但是足够好。在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
因此读取表数据需要3毫秒,这是我们期望的。这也使我得出这样的结论,即花费这么长时间与数据库或数据库连接无关,而可能是在实例化对象时处理返回的数据。表字段及其映射为INT -> int
,VARCHAR -> string
和BIT -> bool
。一个是Nullable
,两个是在生成的构造函数中设置的默认值。
任何想法,这是怎么了?我有什么需要研究的吗?我该怎么做,以进一步调试问题?
谢谢!
更新:
作为D Stanley suggested,它在第二次调用时(20-25毫秒)表现良好。自从我之前打开连接以来,仍然很难理解为什么第一次需要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-25毫秒)表现良好。仍然很难理解为什么[...]
您正在将其与Java进行比较,所以我假设您有使用Java的经验。
与C#的最大区别在于,它在运行时实际上将代码编译为本机代码,这是不平凡的一步。 EF在其之上添加了额外的代码块,因为它会编译您发送给ILASM,然后再发送给本机代码的表达式,这是非常昂贵的。
好处是,一旦编译完成,它将以与本机代码一样快的速度运行-实际上,这甚至更好,因为JIT可以利用其运行的机器来发出其他机器可能不支持的汇编指令(AVX ,SSE等)。