SqlBulkCopy在Azure上使用DataTable比Streaming更快

4
我需要一个工作角色,它从 Blob 中获取 txt 文件,并将其批量插入 Azure Sql 表中。
我正在使用 LumenWorks.Framework.IO 提供的 SqlBulkCopy,我创建了两个版本的工作角色:
1) 读取整个文件,将其加载到 DataTable 中,执行 SqlBulkCopy。 2) StreamRead 文件并将 Stream 传递给 SqlBulkCopy。
问题是第二个版本的性能仅为第一个版本的一半。
例如,对于一个有90,000条记录的10MB txt文件: - 第一个版本:加载文件需用半秒钟,转换为 DataTable 需用2秒钟,SqlBulkCopy 需用20秒钟。 - 第二个版本:总共50秒钟(超过两倍!)
我尝试更改 BatchSize,但似乎没有太大区别,我不知道自己错在哪里,这是第二个版本的代码:
using (var stream = await blockBlob.OpenReadAsync(cancellationToken))
using (var reader = new StreamReader(stream))
using (var csv = new CsvReader(reader, true, ';'))
using (var conn = new SqlConnection(CloudConfigurationManager.GetSetting("TestDbConn")))
{
      await conn.OpenAsync(cancellationToken);
      connAperta = true;
      using (var transaction = conn.BeginTransaction())
      using (var bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.TableLock, transaction))
      {
             bulkCopy.BulkCopyTimeout = 300;
             bulkCopy.DestinationTableName = "[3sc_base_1]";
             await bulkCopy.WriteToServerAsync(csv, cancellationToken);
             transaction.Commit();
      }
}

我做错了什么?

这里的问题是什么?通过 SqlBulkCopy,您可以将整个文件存储在本地内存中,然后将其发送到服务器。通过流式传输,您首先等待 HTTP REST 流传输到您的工作程序,然后将其重定向到 Azure SQL 数据库。当您找到更快的方法时,只需使用它即可。 - astaykov
当然的问题是我想使用流版本,否则如果一次性将它们加载到内存中,对于更大的文件可能会有问题。这两种方法都做同样的事情,它们读取一个文件,然后在数据库上执行一个查询,这意味着逻辑上讲,如果我将这两个操作作为独立操作依次执行,它们不应该比使用流的单个操作更快(至少不会更快)。所以我的结果毫无意义,当然我犯了一个错误,但是那个错误是什么?我认为它与SqlBulkCopy选项有关。 - Simone
那么在这两种情况下,您都是从Blob中读取文件?在第一种情况下,您首先下载文件,然后加载到内存中,然后推送到SqlBulkCopy。而在第二种情况下,您希望直接从Blob流式传输到SQLBulkCopy?并且在这两种情况下,您都是从BLob操作开始测量时间(包括在情况1中下载Blob的时间)? - astaykov
在这两种情况下,我都考虑了整个处理时间,我知道如果SqlBulkCopy将整个文件放入内存中,则可能性能更好,但我认为通过指定BatchSize不应该有任何区别。 - Simone
尝试调整 bulkCopy.BatchSize = 1000; - minghan
1个回答

0

请查看新的Azure SQL数据库功能,可以直接从Azure存储帐户批量上传

除非您不仅要直接流式传输,还要进行转换,否则这应该是实现您想要的最快,最简单的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接