带有大型事务的SQL Server 2008调整(700k +行/事务) [英] Sql Server 2008 Tuning with large transactions (700k+ rows/transaction)

查看:68
本文介绍了带有大型事务的SQL Server 2008调整(700k +行/事务)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在开发一个数据库,该数据库将作为支持数据库添加到我的未来项目中,但是我遇到了一些问题,尤其是日志.

So, I'm working on a database that I will be adding to my future projects as sort of a supporting db, but I'm having a bit of an issue with it, especially the logs.

基本上,数据库每月需要更新一次.必须清除主表,然后从CSV文件中重新填充主表.问题在于Sql Server将为其生成一个MEGA大的日志.我一次成功地填充了它,但想通过清除然后重新填充来测试整个过程.

The database basically needs to be updated once a month. The main table has to be purged and then refilled off of a CSV file. The problem is that Sql Server will generate a log for it which is MEGA big. I was successful in filling it up once, but wanted to test the whole process by purging it and then refilling it.

那是当我收到日志文件已满的错误消息时.它从88MB(通过维护计划缩减后)跃升至248MB,然后完全停止该过程,并且从未完成.

That's when I get an error that the log file is filled up. It jumps from 88MB (after shrinking via maintenance plan) to 248MB and then stops the process altogether and never completes.

我将其增长限制为256MB,增加了16MB,这就是为什么它失败的原因,但实际上我根本不需要它来记录任何内容.有没有一种方法可以完全绕过对数据库运行的任何查询的登录记录?

I've capped it's growth at 256MB, incrementing by 16MB, which is why it failed, but in reality I don't need it to log anything at all. Is there a way to just completely bypass logging on any query being run against the database?

感谢您的任何提前答复!

Thanks for any responses in advance!

根据@ mattmc3的建议,我已经为整个过程实现了SqlBulkCopy.它的工作原理惊人,除了我的循环在某种程度上需要加载的最后一个剩余块崩溃.我不太确定我要去哪里哪里,哎呀,我什至都不知道这是否是正确的循环,因此,我希望能获得一些帮助.

Per the suggestions of @mattmc3 I've implemented SqlBulkCopy for the whole procedure. It works AMAZING, except, my loop is somehow crashing on the very last remaining chunk that needs to be inserted. I'm not too sure where I'm going wrong, heck I don't even know if this is a proper loop, so I'd appreciate some help on it.

我确实知道这与最近的GetDataTable或SetSqlBulkCopy调用有关.我正在尝试插入788189行,进入788000,其余189崩溃...

I do know that its an issue with the very last GetDataTable or SetSqlBulkCopy calls. I'm trying to insert 788189 rows, 788000 get in and the remaining 189 are crashing...

string[] Rows;

using (StreamReader Reader = new StreamReader("C:/?.csv")) {
    Rows = Reader.ReadToEnd().TrimEnd().Split(new char[1] {
        '\n'
     }, StringSplitOptions.RemoveEmptyEntries);
};

int RowsInserted = 0;

using (SqlConnection Connection = new SqlConnection("")) {
    Connection.Open();

    DataTable Table = null;

    while ((RowsInserted < Rows.Length) && ((Rows.Length - RowsInserted) >= 1000)) {
        Table = GetDataTable(Rows.Skip(RowsInserted).Take(1000).ToArray());

        SetSqlBulkCopy(Table, Connection);

        RowsInserted += 1000;
    };

    Table = GetDataTable(Rows.Skip(RowsInserted).ToArray());

    SetSqlBulkCopy(Table, Connection);

    Connection.Close();
};

static DataTable GetDataTable(
    string[] Rows) {
    using (DataTable Table = new DataTable()) {
        Table.Columns.Add(new DataColumn("A"));
        Table.Columns.Add(new DataColumn("B"));
        Table.Columns.Add(new DataColumn("C"));
        Table.Columns.Add(new DataColumn("D"));

        for (short a = 0, b = (short)Rows.Length; a < b; a++) {
            string[] Columns = Rows[a].Split(new char[1] {
                ','
            }, StringSplitOptions.RemoveEmptyEntries);

            DataRow Row = Table.NewRow();

            Row["A"] = Columns[0];
            Row["B"] = Columns[1];
            Row["C"] = Columns[2];
            Row["D"] = Columns[3];

            Table.Rows.Add(Row);
        };

        return (Table);
    };
}

static void SetSqlBulkCopy(
    DataTable Table,
    SqlConnection Connection) {
    using (SqlBulkCopy SqlBulkCopy = new SqlBulkCopy(Connection)) {
        SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("A", "A"));
        SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("B", "B"));
        SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("C", "C"));
        SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("D", "D"));

        SqlBulkCopy.BatchSize = Table.Rows.Count;
        SqlBulkCopy.DestinationTableName = "E";
        SqlBulkCopy.WriteToServer(Table);
    };
}

编辑/最终代码:这样,该应用程序现在已完成并可以惊人地运行,而且速度非常快! @ mattmc3,感谢您的所有帮助!这是可能有用的任何人的最终代码:

EDIT/FINAL CODE: So the app is now finished and works AMAZING, and quite speedy! @mattmc3, thanks for all the help! Here is the final code for anyone who may find it useful:

List<string> Rows = new List<string>();

using (StreamReader Reader = new StreamReader(@"?.csv")) {
    string Line = string.Empty;

    while (!String.IsNullOrWhiteSpace(Line = Reader.ReadLine())) {
        Rows.Add(Line);
    };
};

if (Rows.Count > 0) {
    int RowsInserted = 0;

    DataTable Table = new DataTable();

    Table.Columns.Add(new DataColumn("Id"));
    Table.Columns.Add(new DataColumn("A"));

    while ((RowsInserted < Rows.Count) && ((Rows.Count - RowsInserted) >= 1000)) {
        Table = GetDataTable(Rows.Skip(RowsInserted).Take(1000).ToList(), Table);

        PerformSqlBulkCopy(Table);

        RowsInserted += 1000;

        Table.Clear();
    };

    Table = GetDataTable(Rows.Skip(RowsInserted).ToList(), Table);

    PerformSqlBulkCopy(Table);
};

static DataTable GetDataTable(
    List<string> Rows,
    DataTable Table) {
    for (short a = 0, b = (short)Rows.Count; a < b; a++) {
        string[] Columns = Rows[a].Split(new char[1] {
            ','
        }, StringSplitOptions.RemoveEmptyEntries);

        DataRow Row = Table.NewRow();

        Row["A"] = "";

        Table.Rows.Add(Row);
    };

    return (Table);
}

static void PerformSqlBulkCopy(
    DataTable Table) {
    using (SqlBulkCopy SqlBulkCopy = new SqlBulkCopy(@"", SqlBulkCopyOptions.TableLock)) {
        SqlBulkCopy.BatchSize = Table.Rows.Count;
        SqlBulkCopy.DestinationTableName = "";
        SqlBulkCopy.WriteToServer(Table);
    };
}

推荐答案

如果要对SQL Server中的表进行批量插入,则应这样做(BCPBulk Insert或.NET中的SqlBulkCopy类),则可以使用批量记录"恢复模型.我强烈建议阅读有关恢复模型的MSDN文章: http://msdn.microsoft. com/en-us/library/ms189275.aspx

If you are doing a Bulk Insert into the table in SQL Server, which is how you should be doing this (BCP, Bulk Insert, Insert Into...Select, or in .NET, the SqlBulkCopy class) you can use the "Bulk Logged" recovery model. I highly recommend reading the MSDN articles on recovery models: http://msdn.microsoft.com/en-us/library/ms189275.aspx

这篇关于带有大型事务的SQL Server 2008调整(700k +行/事务)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆