c# - 使用带有 SQL Server OPENROWSET 文件规范的管道
问题描述
我们得到了一些非常大的 .tar.gz 文件,我们希望将它们加载到 SQL Server 中(例如 3 gig gzip 压缩,20 gig 未压缩)。
我想我会尝试通过编写一个 C# 层来使用命名管道即时解压缩并流式传输到 SQL Server,从而节省一些时间和磁盘空间。
我发现了这一点:Sql Server BULK INSERT 可以从命名管道/fifo 中读取吗?
并且两个答案都有一些“我们不知道为什么这是必要的,但否则它不起作用”评论
- 需要打开 2 个管道和
- 需要在对 SQL Server 的一次大写中完成所有操作
写 1 个大型 20 gig 并不实际,所以我在修改上述解决方案中的代码。
我发现当我
byte[] buff = new byte[<pick your size here>];
int readlen;
while ((readlen = inputStream.Read(buff, 0, buff.Length)) > 0)
{
pipeStream.Write(buff, 0, readlen);
pipeStream.WaitForPipeDrain();
}
无论缓冲区大小是多少,我都会收到 2 次写入,并且在第三次几乎都会收到“管道损坏”错误。
原来我试过
inputStream.CopyTo(pipeStream);
并且默认使用 80k 缓冲区。看着Position
,我可以看到它爆炸时我会在第三次写。
知道 SQL Server 端在 2 次读取后可能会发生什么中断吗?
编辑:我做了一些尝试,发现缓冲区越大,它会越远。当我的缓冲区超过 1 兆时,在管道破裂之前,我几乎有 2 个演出被写入管道。超过 5 兆缓冲区并没有改善情况。
起初我认为解压缩 zip 的开销可能会导致读取滞后于写入,因此 Sql Server 可能会因读取超时或其他原因而关闭。我使读取和写入异步,因此我可以在写入发生时进行下一次读取,但这没有帮助。
我添加了一些时间,结果发现管道写入所花费的时间是 gzip 读取时间的 2.5 倍,所以我不知道为什么管道最终会中断。
仍然几乎 2 gig 远比 2-3 写几百 K
解决方案
推荐阅读
- python - 将整个函数作为字符串 / 并将字符串转换为函数?
- swift - 无法使用 ViewModel 加载数据
- scala - 当状态满足某些条件时如何停止状态转换?
- ruby-on-rails - Heroku 拒绝来自 Ruby on Rails 应用程序的推送
- vba - VBLOOKUP 和 MATCH 识别列中的问题
- django - Django rest 框架 serializer.errors 输出 ["This field is required."] 与 multipart/form-data 发布请求
- node.js - SAP 全栈 Web IDE 构建错误
- laravel-5.4 - 如何在 Laravel 5.4 中更新多个图像并删除旧图像?
- vba - 根据值将行中的数据汇总到列中 - 而不是简单地转置
- c# - Twilio 功能读取多个语音输入