SqlBulkCopy Azure DataTable 比流式传输更快
Posted
技术标签:
【中文标题】SqlBulkCopy Azure DataTable 比流式传输更快【英文标题】:SqlBulkCopy Azure DataTable faster than Streaming 【发布时间】:2015-01-14 08:05:15 【问题描述】:我需要一个辅助角色,它从 Blob 中获取一个 txt 文件并将其批量放入 Azure Sql 表中。
我使用的是 LumenWorks.Framework.IO 提供的 SqlBulkCopy, 我创建了 2 个版本的 worker 角色: 1)读取整个文件,加载到DataTable中,执行SqlBulkCopy 2) Stream读取文件并将Stream传递给SqlBulkCopy
问题是第二个版本的性能只有第一个版本的一半。
以 10MB txt 文件为例,其中包含 90'000 条记录: -第一个版本:半秒加载文件,2秒转换为DataTable,20秒为SqlBulkCopy
-second 版本:总共 50 秒(超过两倍!)
我尝试更改 BatchSize,但似乎没有太大区别,我不知道我做错了什么,这是 2' 版本代码:
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 数据库。当你发现更快的时候,就用它吧。 问题当然是我想使用流版本,否则如果我一次将它们加载到内存中,我可能会遇到更大的文件问题。这两种方法做同样的事情,它们读取一个文件,然后对数据库执行一个查询,这意味着从逻辑上讲,如果我将这两个操作作为独立操作一个接一个地执行,它们不应该比使用单个操作更快使用流(至少没那么快)。所以我的结果没有意义,当然我犯了一个错误,但那个错误是什么?我认为它与 SqlBulkCopy 选项有关 所以在这两种情况下,您都是从 Blob 读取文件?以防万一您先下载文件,然后加载到内存中,然后推送到 SqlBulkCopy。在第二种情况下,您想从 Blob 流直接流式传输到 SQLBulkCopy?在这两种情况下,您首先测量从 Blob 操作开始的时间(包括您的情况 1 中的 Blob 下载时间)? 确切地说,在这两种情况下,我都考虑了整个过程时间,我知道如果 SqlBulkCopy 将整个文件都放在内存中,它的性能会更好,但我认为通过指定 BatchSize 它不应该产生任何影响区别 尝试调整bulkCopy.BatchSize = 1000;
【参考方案1】:
查看bulk upload directly from an Azure Storage account 的新 Azure SQL 数据库功能。
这应该是实现您想要的最快和最简单的方法,除非您不是直接流式传输而是同时进行转换。
【讨论】:
以上是关于SqlBulkCopy Azure DataTable 比流式传输更快的主要内容,如果未能解决你的问题,请参考以下文章