2016-01-07 2 views
1

У меня есть таблица с 1 миллионом записей. Мне нужно перенести эти записи в другую базу данных и другую таблицу.SQL Server bulkcopy insert миллион записей медленный

Я использую хранимую процедуру для получения данных. Он заполняет адаптер данных, а затем bcp - данные в новую таблицу.

Мы находимся на SQL Server 2005 и C# 4. Мы перейдем на SQL Server 2012 или 2014 и Visual Studio 2015 с C# 4.6 или 5.0. Если есть какие-либо функции, которые сделают эту работу хорошо.

  • для 10k записывает этот процесс занимает менее 1 секунды
  • для 500k записей, то DataAdapter бежит из памяти, и процесс выходит из строя. до 100 тыс. Записей, запрос выбора - проблема в SQL, возвращающая 100 тыс. Записей за раз, занимает 2 минуты за цикл.

Есть ли способ, или что случилось с моим кодом ниже, чтобы адаптер данных от заполнения и вместо того, чтобы отображать столбцы и имеет боковую BulkCopy пребывания сервера и просто раздвинуть записи из БДА в новую таблицу например, SSIS?

Кажется, что основная копия сама по себе молниеносно, но заполнение адаптера завершается неудачно, потому что в нем не хватает памяти, пытаясь заполнить адаптер 1 миллионом записей. Без выполнения 1 строки за раз, я бы просто хотел переместить данные между таблицами.

В одной таблице имеется 27 столбцов с 5 столбцами, не находящимися в таблице 2, которая имеет 32 столбца, а некоторые столбцы не называются одинаковыми в обеих таблицах.

Это доказательство концепции (PoC).

sourceConn_transDB.Open(); 
SqlCommand sourceCommand = new SqlCommand(queryString, sourceConn_transDB); 
DataTable table = new DataTable(); 

sourceCommand.CommandTimeout = 600; 

using (var adapter = new SqlDataAdapter(sourceCommand)) 
{ 
    WriteLineWithTime("Adapter Fill"); 
    adapter.Fill(table); 
} 

if ((table == null) || (table.Rows.Count <= 0)) 
    break; 

using (SqlBulkCopy bulk = new SqlBulkCopy(targetConn_reportDB, SqlBulkCopyOptions.KeepIdentity, null) { DestinationTableName = "PatientEvent" }) 
{ 
    bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping("PatientID", "PatientID")); 
} 

ответ

4

Вы пробовали с помощью WriteToServer перегрузок, которые принимают IDataReader, то вам не нужно использовать DataTable вообще.

sourceConn_transDB.Open(); 
using(SqlCommand sourceCommand = new SqlCommand(queryString, sourceConn_transDB)) 
{ 
    sourceCommand.CommandTimeout = 600; 

    using (SqlDataReader reader = sourceCommand.ExecuteReader()) 
    using (SqlBulkCopy bulk = new SqlBulkCopy(targetConn_reportDB, SqlBulkCopyOptions.KeepIdentity, null) { DestinationTableName = "PatientEvent" }) 
    { 
     bulk.ColumnMappings.Add(new SqlBulkCopyColumnMapping("PatientID", "PatientID")); 
     bulk.WriteToServer(reader); 
    } 
} 
+0

Попробуй это сейчас. Я считаю, что это именно то, что я ищу, и не смог найти. –

+0

Это было, спасибо. только отсутствовал targetConn_reportDB.Open() перед bulk.writetoserver .... –

Смежные вопросы