Memory sqlbulkcopy mem。管理

Memory sqlbulkcopy mem。管理,memory,datatable,sqlbulkcopy,Memory,Datatable,Sqlbulkcopy,我使用SQLBULKCOPY将一些数据表复制到数据库表中,但是,由于我复制的文件的大小有时超过600mb,所以内存一直不足 我希望在将表提交到数据库之前获得一些关于管理表大小的建议,以便释放一些内存以继续编写 下面是我的一些代码示例(为了简单起见,删除了一些列和行) 我在让SQLBulkCopy正常工作时仍然遇到问题,我意识到在将每条记录输入数据库之前,我需要对其进行更多的工作,因此我开发了一个简单的LinQ to Sql方法来逐个记录更新,以便在运行时编辑其他信息并创建更多记录信息 问题:这

我使用SQLBULKCOPY将一些数据表复制到数据库表中,但是,由于我复制的文件的大小有时超过600mb,所以内存一直不足

我希望在将表提交到数据库之前获得一些关于管理表大小的建议,以便释放一些内存以继续编写

下面是我的一些代码示例(为了简单起见,删除了一些列和行)


我在让SQLBulkCopy正常工作时仍然遇到问题,我意识到在将每条记录输入数据库之前,我需要对其进行更多的工作,因此我开发了一个简单的LinQ to Sql方法来逐个记录更新,以便在运行时编辑其他信息并创建更多记录信息

问题:这种方法运行得非常慢(即使在Core i3机器上),有没有关于如何加速它的想法(线程?)——在单处理器内核上,1gb内存会崩溃,或者有时需要6-8个小时才能写入与一个SQLBulkCopy相同数量的数据,这需要一些时间。不过,它确实可以更好地管理内存

            while ((inputLine = rdr.ReadLine()) != null) //Read while the line is not null
        {
            Console.Write("\rWriting Line: {0}", k);
            string[] arr;              
            arr = inputLine.Split('\t');

            /* items */
            if (fileName.Contains(",,"))
            {
                Item = Table(arr);
               table.tables.InsertOnSubmit(Item);

                /* Check to see if the item is in the db */
                bool exists = table.tables.Where(u => u.ProductID == Item.ProductID).Any();

                /* Commit */
                if (!exists)
                {
                    try
                    {
                        table.SubmitChanges();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        // Make some adjustments.
                        // ...
                        // Try again.
                        table.SubmitChanges();
                    }
                }
            }
使用助手方法:

    public static class extensionMethods
{
    /// <summary>
    /// Method that provides the T-SQL EXISTS call for any IQueryable (thus extending Linq).
    /// </summary>
    /// <remarks>Returns whether or not the predicate conditions exists at least one time.</remarks>
    public static bool Exists<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
    {
        return source.Where(predicate).Any();
    }
}
公共静态类扩展方法
{
/// 
///方法,该方法为任何IQueryable(从而扩展Linq)提供T-SQL EXISTS调用。
/// 
///返回谓词条件是否至少存在一次。
存在公共静态bool(此IQueryable源、表达式谓词)
{
返回source.Where(谓词).Any();
}
}

尝试将BatchSize属性指定为1000,这将在1000记录批次而不是整个批次中批量插入。您可以调整此值以找到最佳值。我使用了sqlbulkcopy来处理相似大小的数据,效果很好

面对相同的问题,发现OutOfMemory异常的问题在DataTable.Rows最大数量限制中。 通过重新创建表解决,最大行数限制为500000行。 希望我的解决方案能有所帮助:

var myTable = new System.Data.DataTable();
myTable.Columns.Add("Guid", typeof(Guid));
myTable.Columns.Add("Name", typeof(string));

int counter = 0;

foreach (var row in rows)
{
    ++counter;

    if (counter < 500000)
    {
        myTable.Rows.Add(
            new object[]
            {
                row.Value.Guid,
                row.Value.Name
            });
    }
    else
    {
        using (var dbConnection = new SqlConnection("Source=localhost;..."))
        {
            dbConnection.Open();
            using (var s = new SqlBulkCopy(dbConnection))
            {
                s.DestinationTableName = "MyTable";

                foreach (var column in myTable.Columns)
                    s.ColumnMappings.Add(column.ToString(), column.ToString());

                try
                {
                    s.WriteToServer(myTable);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    s.Close();
                }
            }
        }

        myTable = new System.Data.DataTable();
        myTable.Columns.Add("Guid", typeof(Guid));
        myTable.Columns.Add("Name", typeof(string));

        myTable.Rows.Add(
            new object[]
            {
                row.Value.Guid,
                row.Value.Name
            });

        counter = 0;

    }
}
var myTable=new System.Data.DataTable();
添加(“Guid”,typeof(Guid));
添加(“名称”,typeof(字符串));
int计数器=0;
foreach(行中的变量行)
{
++计数器;
如果(计数器<500000)
{
myTable.Rows.Add(
新对象[]
{
row.Value.Guid,
row.Value.Name
});
}
其他的
{
使用(var dbConnection=newsqlconnection(“Source=localhost;…))
{
dbConnection.Open();
使用(var s=newsqlbulkcopy(dbConnection))
{
s、 DestinationTableName=“MyTable”;
foreach(myTable.Columns中的var列)
s、 添加(column.ToString(),column.ToString());
尝试
{
s、 WriteToServer(myTable);
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
}
最后
{
s、 Close();
}
}
}
myTable=新的System.Data.DataTable();
添加(“Guid”,typeof(Guid));
添加(“名称”,typeof(字符串));
myTable.Rows.Add(
新对象[]
{
row.Value.Guid,
row.Value.Name
});
计数器=0;
}
}

也许在银行处理rdr也是一个好主意——我会记住这一点,我想知道,如果我在阅读完每个文件之前处理完我的阅读器,我会在直接阅读时放慢速度,在阅读时会出现内存不足错误,而不是在写作时。。。有没有想过我将如何跳回我在文件中的位置?谢谢,我添加了这个,并开始写每10万条记录,我认为我的问题在于文件阅读器对象,因为我每次都在同一个位置耗尽内存--试图找出如何在我现在直接阅读时保持文件中的位置…我仍然不认为文件流是问题所在。您是否尝试过批量大小为1000左右?显然,以大约1000-2000的记录进行批处理是最有效的。如果您确定它是文件,您可以做的是打开文件,读取一千条记录,存储位置,进行大容量插入,然后关闭文件。再次打开它,将位置设置为最后一个位置并读取另一批。你一定是对的,因为我在“try”块中有实际副本,并且我得到了内存不足异常,因此它必须与try块中的某些内容相关,否则我将无法正确处理它。我将尝试保存文件位置并报告结果。
var myTable = new System.Data.DataTable();
myTable.Columns.Add("Guid", typeof(Guid));
myTable.Columns.Add("Name", typeof(string));

int counter = 0;

foreach (var row in rows)
{
    ++counter;

    if (counter < 500000)
    {
        myTable.Rows.Add(
            new object[]
            {
                row.Value.Guid,
                row.Value.Name
            });
    }
    else
    {
        using (var dbConnection = new SqlConnection("Source=localhost;..."))
        {
            dbConnection.Open();
            using (var s = new SqlBulkCopy(dbConnection))
            {
                s.DestinationTableName = "MyTable";

                foreach (var column in myTable.Columns)
                    s.ColumnMappings.Add(column.ToString(), column.ToString());

                try
                {
                    s.WriteToServer(myTable);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    s.Close();
                }
            }
        }

        myTable = new System.Data.DataTable();
        myTable.Columns.Add("Guid", typeof(Guid));
        myTable.Columns.Add("Name", typeof(string));

        myTable.Rows.Add(
            new object[]
            {
                row.Value.Guid,
                row.Value.Name
            });

        counter = 0;

    }
}