【问题标题】:Write blob sequentially in varbinary column在 varbinary 列中顺序写入 blob
【发布时间】:2014-04-07 12:26:11
【问题描述】:

我必须将一些数据库恢复到远程 SQL Server。问题是它们最多可以达到几 GB,这会在一次读取所有字节时导致“OutOfMemory”异常。在较小的数据库上,它可以正常工作..

现在我尝试在这里将数据库按顺序流式传输到 SQL Server:

using (System.Data.SqlClient.SqlCommand command = conn.CreateCommand())
{
    command.CommandText = "INSERT INTO " + dbName + ".dbo.tempTable (blob) values (@data)";
    command.CommandTimeout = 900;

    SqlParameter dataParam = new SqlParameter("@data", SqlDbType.VarBinary);
    command.Parameters.Add(dataParam);

    SqlParameter offsetParam = new SqlParameter("@offset", SqlDbType.BigInt);
    command.Parameters.Add(offsetParam);

    SqlParameter lengthParam = new SqlParameter("@len", SqlDbType.BigInt);
    command.Parameters.Add(lengthParam);

    using (FileStream fs = new FileStream(fileSource, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        byte[] buffer = new byte[8192];
        int read = 0;
        int offset = 0;

        while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
        {
            dataParam.Value = buffer;
            offsetParam.Value = offset;
            lengthParam.Value = read;

            command.ExecuteNonQuery();

            if (offset == 0)
            {
               command.CommandText = "UPDATE " + dbName + ".dbo.tempTable SET blob.WRITE(@data, @offset, @len)";
            }

            offset += read;
         }
     }
}

现在我的问题:

一个 500mb 的数据库需要超过 15 分钟,然后它停止工作并出现此异常:

System.Data.Common.DbException:超时。在操作完成之前超时时间已过或服务器没有响应。

提前致谢,

放松

【问题讨论】:

    标签: c# sql sql-server sequential varbinary


    【解决方案1】:

    我怀疑超时是由于性能问题。我的猜测(没有任何数据支持,请注意)是阻塞。有些东西会阻止您的查询执行。阅读How to analyse SQL Server performance 以获取如何分析性能问题(例如您的问题、测量什么、查看什么等)的提示。

    请注意,您的 UPDATE ... column.WRITE ... 是 Operations That Can Be Minimally Logged 的主要候选者,请务必阅读 The Data Loading Performance Guide。

    作为旁注,我有一篇文章准确描述了您的技术,包括对 BLOB 的阅读:Download and Upload images from SQL Server via ASP.Net MVC。

    【讨论】:

    • 顺便说一句,我不赞成将数据库流式传输到 BLOB 列中的想法,这是我对您正在做的事情的理解。使用文件传输协议。
    • 你可能有这样的例子?我的公司有一些限制,但也许有更好的方法。
    【解决方案2】:

    我现在已经自己解决了。问题是我创建了一个 8040 字节的字节数组。这将适用于大约 50000 个请求的 520mb 数据库。我现在已将字节大小更改为 8MB。

    byte[] buffer = new byte[8388608];
    

    现在效果很好;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 2015-10-25
      • 2020-11-07
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 2015-03-22
      相关资源
      最近更新 更多