gpt4 book ai didi

sql-server-2005 - 如何将慢速参数化插入更改为快速批量复制(甚至从内存中)

转载 作者:行者123 更新时间:2023-12-01 07:09:12 25 4
gpt4 key购买 nike

我的代码中有这样的东西(.Net 2.0,MS SQL)

SqlConnection connection = new SqlConnection(@"Data Source=localhost;Initial
Catalog=DataBase;Integrated Security=True");
connection.Open();

SqlCommand cmdInsert = connection.CreateCommand();
SqlTransaction sqlTran = connection.BeginTransaction();
cmdInsert.Transaction = sqlTran;

cmdInsert.CommandText =
@"INSERT INTO MyDestinationTable" +
"(Year, Month, Day, Hour, ...) " +
"VALUES " +
"(@Year, @Month, @Day, @Hour, ...) ";

cmdInsert.Parameters.Add("@Year", SqlDbType.SmallInt);
cmdInsert.Parameters.Add("@Month", SqlDbType.TinyInt);
cmdInsert.Parameters.Add("@Day", SqlDbType.TinyInt);
// more fields here
cmdInsert.Prepare();

Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

StreamReader reader = new StreamReader(stream);
char[] delimeter = new char[] {' '};
String[] records;
while (!reader.EndOfStream)
{
records = reader.ReadLine().Split(delimeter, StringSplitOptions.None);

cmdInsert.Parameters["@Year"].Value = Int32.Parse(records[0].Substring(0, 4));
cmdInsert.Parameters["@Month"].Value = Int32.Parse(records[0].Substring(5, 2));
cmdInsert.Parameters["@Day"].Value = Int32.Parse(records[0].Substring(8, 2));
// more here complicated stuff here
cmdInsert.ExecuteNonQuery()
}
sqlTran.Commit();
connection.Close();

将 cmdInsert.ExecuteNonQuery() 注释掉后,这段代码的执行时间不到 2 秒。 SQL 执行需要 1m 20 秒。大约有 50 万条记录。表之前被清空。类似功能的 SSIS 数据流任务大约需要 20 秒。
  • 批量插入 不是一个选项(见下文)。我在这个导入过程中做了一些花哨的东西。
  • 我的测试机器是 Core 2 Duo 和 2 GB RAM。
  • 在任务管理器中查看时,CPU 尚未完全化。 IO 似乎也没有被充分利用。
  • Schema 非常简单:一张表以 AutoInt 作为主索引,并且少于 10 个整数、小整数和字符 (10)。

  • 经过这里的一些回答后,我发现可以执行 从内存中批量复制 !我拒绝使用批量复制,因为我认为它必须从文件中完成...

    现在我使用它,它需要大约 20 秒(如 SSIS 任务)
      DataTable dataTable = new DataTable();

    dataTable.Columns.Add(new DataColumn("ixMyIndex", System.Type.GetType("System.Int32")));
    dataTable.Columns.Add(new DataColumn("Year", System.Type.GetType("System.Int32")));
    dataTable.Columns.Add(new DataColumn("Month", System.Type.GetType("System.Int32")));
    dataTable.Columns.Add(new DataColumn("Day", System.Type.GetType("System.Int32")));
    // ... and more to go

    DataRow dataRow;
    object[] objectRow = new object[dataTable.Columns.Count];

    Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

    StreamReader reader = new StreamReader(stream);
    char[] delimeter = new char[] { ' ' };
    String[] records;
    int recordCount = 0;
    while (!reader.EndOfStream)
    {
    records = reader.ReadLine().Split(delimeter, StringSplitOptions.None);

    dataRow = dataTable.NewRow();
    objectRow[0] = null;
    objectRow[1] = Int32.Parse(records[0].Substring(0, 4));
    objectRow[2] = Int32.Parse(records[0].Substring(5, 2));
    objectRow[3] = Int32.Parse(records[0].Substring(8, 2));
    // my fancy stuf goes here

    dataRow.ItemArray = objectRow;
    dataTable.Rows.Add(dataRow);

    recordCount++;
    }

    SqlBulkCopy bulkTask = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null);
    bulkTask.DestinationTableName = "MyDestinationTable";
    bulkTask.BatchSize = dataTable.Rows.Count;
    bulkTask.WriteToServer(dataTable);
    bulkTask.Close();

    最佳答案

    不要单独插入每条记录,而是尝试使用 SqlBulkCopy类一次批量插入所有记录。

    创建一个数据表并将所有记录添加到数据表中,然后使用 SqlBulkCopy . WriteToServer一次批量插入所有数据。

    关于sql-server-2005 - 如何将慢速参数化插入更改为快速批量复制(甚至从内存中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/127152/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com