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

  • 时间:
  • 浏览:4
  • 来源:极速快3_快3是真的吗_极速快3是真的吗

刚刚发布过一篇博文 下单快发货慢:4个 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 时增加了4个 字段引起的, 加上一种生活字段,难题图片立马消失。进一步测试发现,假若任意加上 SELECT 中的4个 字段,就后会出现难题图片,太奇怪了。数了数 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 的4个 大 bug ,4个 潜藏你要(至少从 .NET Core 2.1 到 3.0 Preview 4)的巨坑。

一种生活诡异难题图片的谜底在偶然间终于被解开了,这时又产生了新的难题图片 —— corefx 中是如何修复一种生活巨坑 bug 的?

查看 corefx 中与 System.Data.SqlClient 相关的 git commits ,目测发现下面的 commit (对应的 PR ),你爱不爱我是一种生活 commit 修复的,接下来找时间验证一下。