坑暗花明:又遇 .NET Core 中 System.Data.SqlClient 查询缓慢的问题

  • 时间:
  • 浏览:6
  • 来源:1分时时彩官网_1分时时彩下注平台_1分时时彩游戏平台

以后发布过一篇博文 下单快发货慢:另另另一个 JOIN SQL 引起 SqlClient 读取数据慢的奇特大问提,当时遇到的大问提是从 SQL Server 4008 R2 中查询获取 400 条记录竟然耗时 10 多秒,排查中发现大问提与 SQL  查询中暗含 INNER JOIN 有关,再加 INNER JOIN 立马查询越来更慢。当时天真地以为意味着着 是 JOIN 的那张表数据记录太久以及主表聚集索引不合理,于是采用将 INNER JOIN 累积拆分出来单独查询临时避免了大问提。

这4天 大家 又在另外另另另一个 ASP.NET Core 2.2 项目中也遇到了查询 400 数据库记录效率慢(需要4~6秒)的大问提,有以后所查询的数据库表数据量并需要 很大。通过 EF Core 的 日志记录发现耗时地处在 Executed DbCommand 时,耗时地处点与以后的情况表不一样,以后是地处在 Executed DbCommand 以后 SqlDataReader 从数据库读取数据时。

2019-05-11T14:21:38.1015229+08:00 [INFORMATION] Executed DbCommand ("5,8400"ms)

而通过 SQL Server Management Studio 执行同样的 SQL 搞笑的话只需要 20 毫秒左右,相差400多倍。

Executed DbCommand 日志记录的是 dbCommand.ExecuteReaderAsync 执行的时间(详见 EF Core 的源码)

result = new RelationalDataReader(
    connection,
    dbCommand,
    await dbCommand.ExecuteReaderAsync(cancellationToken),
    commandId,
    Logger);

dbCommand.ExecuteReaderAsync 的实现代码在 corefx 的 System.Data.SqlClient 中,意味着着 是 .net core 的大问提,那大问提就出在 System.Data.SqlClient 。

在上次排查 SqlDataReader 读取数据效率慢大问提,就曾怀疑 System.Data.SqlClient ,花了可是我有时间在 System.Data.SqlClient 的源码中打点排查,最终这麼找到线索,这次不敢轻易怀疑它。

实在这次的耗时地处点与上次不一样,但这次的 SQL 查询搞笑的话暗含个地方和上次是一样的,也暗含 INNER JOIN 查询,于是试着再加 INNER JOIN ,Executed DbCommand 只需2毫秒。

[INFORMATION] Executed DbCommand ("2"ms)

啊,为社 会么会也与 INNER JOIN 有关,没道理啊,这次 JOIN 的表数据量不大,完全不意味着着 造成 400 多倍的性能之差。看来上次归罪于 INNER JOIN ,意味着着 是冤枉它了,得重新思考与排查这些大问提。

意味着着 大问提是在某个时间点以后跳出 ,于是采取笨辦法 ,回退 git 提交历史直至大问提消失。。。

最终发现,竟然是在一次 git commit 中给这些查询在 SELECT 时增加了另另另一个字段引起的, 再加这些字段,大问提立马消失。进一步测试发现,假如任意再加 SELECT 中的另另另一个字段,就不让跳出 大问提,太奇怪了。数了数 SELECT 暗含20个字段,难道与 SELECT 字段的数量有关?以后的项目会不让也与 SELECT 字段的数量有关?

于是回到以后的项目,恢复 INNER JOIN 查询,这时惊讶地发现 SqlDataReader 读取数据效率慢的大问提竟然消失了。回想当时避免大问提后到现在所做的变更,唯一的变更可是我从 .NET Core 3.0 Preivew 4 升级到 .NET Core 3.0 Preivew 5 ,难道 3.0 Preivew 5 把这些大问提给修复了?难道真的是 System.Data.SqlClient 的 bug ?

答案很容易验证,将当前遇到 Executed DbCommand 执行慢的项目升级到 .NET Core 3.0 Preivew 5 ,昨天晚上完成升级后

Executed DbCommand ("3"ms)

飞流直下三千尺,从4秒骤降到3毫秒,相差4000多倍!你造是 System.Data.SqlClient 的另另另一个大 bug ,另另另一个潜藏以后(为宜从 .NET Core 2.1 到 3.0 Preview 4)的巨坑。

这些诡异大问提的谜底在偶然间终于被解开了,这时又产生了新的大问提 —— corefx 中是咋样修复这些巨坑 bug 的?

查看 corefx 中与 System.Data.SqlClient 相关的 git commits ,目测发现下面的 commit (对应的 PR ),你说什么是这些 commit 修复的,接下来找时间验证一下。