我试图从格式化为 JSON 的 SQL Server 2016 数据库返回相当大的数据集(数千行)(使用 SQL Server 2016 的 FOR JSON AUTO 功能);但是,我在读取 SqlDataReader 的结果时遇到了问题。
我之前将结果作为常规行加载到 DataTable 中,效果非常好(加载整个表大约需要 10-15 秒)。但是,如果我尝试使用相同的数据构建以 JSON 形式返回的字符串,则需要几分钟的时间来构建从 DataReader 返回的字符串。我想补充一点,我还在这个查询中返回了大量的二进制数据(我有试图从数据库检索的 SqlGeometry 对象)。我从这里返回的典型字符串有几个 100k 个字符长,并且阅读器的读取速度非常慢。
无论如何,我解析 JSON 的加载代码如下:
public static Task<string> ExecuteJsonReaderAsync(string connectionString, CommandType commandType, string commandText, SqlParameter[] oParams = null, int timeout = 30, CancellationToken token = default(CancellationToken))
{
return Task<string>.Factory.StartNew(() =>
{
var str = string.Empty;
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = new SqlCommand(commandText, connection))
{
command.CommandTimeout = timeout;
command.CommandType = commandType;
if (oParams?.Length > 0) command.Parameters.AddRange(oParams);
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
str = $"{str}{reader[0]}";
}
reader.Close();
}
return str;
}
}
}, token);
}
我尝试了各种命令选项来尝试加快速度,包括 CloseConnection、SequentialAccess、SingleResult,但无济于事。为什么构建字符串比从相同数据加载数据表花费的时间要长得多,有没有更快的方法来实现这一点?
我认为这一定是我做错了或者我忽略了,我希望有人以前遇到过这个问题。有什么想法吗?
最佳答案
您的代码在每个循环中重新分配内存中的字符串变量。这不利于代码的性能。相反,类 StringBuilder有一个内部缓冲区,允许更少的内存重新分配,如果您知道数据的总长度,您还可以控制该缓冲区的大小,以避免发生重新分配。
所以
// Set an initial capacity of 1MB
StringBuilder str = new StringBuidler(1024*1024);
while (reader.Read())
{
str.Append(reader[0].ToString());
}
....
return str.ToString();
有关 C# string immutable concept here 的更多信息
关于c# - 从 SqlDataReader 读取 JSON 字符串的最有效和最快的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42798446/