Самый быстрый способ обновить (заполнить) 1,000,000 записей в базе данных с помощью .NET.

Я использую этот код, чтобы вставить 1 миллион записей в пустую таблицу в базе данных. Итак, без большого кода я начну с точки, с которой я уже взаимодействовал с данными, и прочитал схему в DataTable:

Итак:

DataTable returnedDtViaLocalDbV11 = DtSqlLocalDb.GetDtViaConName(strConnName, queryStr, strReturnedDtName);

И теперь, когда мы returnedDtViaLocalDbV11, создадим новый DataTable для клонирования таблицы исходной базы данных:

DataTable NewDtForBlkInsert = returnedDtViaLocalDbV11.Clone();

Stopwatch SwSqlMdfLocalDb11 = Stopwatch.StartNew();
NewDtForBlkInsert.BeginLoadData();

for (int i = 0; i < 1000000; i++)
{
   NewDtForBlkInsert.LoadDataRow(new object[] { null, "NewShipperCompanyName"+i.ToString(), "NewShipperPhone" }, false);
}
NewDtForBlkInsert.EndLoadData();

DBRCL_SET.UpdateDBWithNewDtUsingSQLBulkCopy(NewDtForBlkInsert, tblClients._TblName, strConnName);

SwSqlMdfLocalDb11.Stop();

var ResSqlMdfLocalDbv11_0 = SwSqlMdfLocalDb11.ElapsedMilliseconds;

Этот код заполняет 1 миллион записей во встроенную базу данных SQL (localDb) в 5200 мс. Остальная часть кода просто реализует bulkCopy, но я все равно отправлю его.

 public string UpdateDBWithNewDtUsingSQLBulkCopy(DataTable TheLocalDtToPush, string TheOnlineSQLTableName, string WebConfigConName)
 {
    //Open a connection to the database. 
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[WebConfigConName].ConnectionString))
    {
       connection.Open();

       // Perform an initial count on the destination table.
       SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM "+TheOnlineSQLTableName +";", connection);
       long countStart = System.Convert.ToInt32(commandRowCount.ExecuteScalar());

       var nl = "\r\n";
       string retStrReport = "";
       retStrReport = string.Concat(string.Format("Starting row count = {0}", countStart), nl);
       retStrReport += string.Concat("==================================================", nl);
       // Create a table with some rows. 
       //DataTable newCustomers = TheLocalDtToPush;

       // Create the SqlBulkCopy object.  
       // Note that the column positions in the source DataTable  
       // match the column positions in the destination table so  
       // there is no need to map columns.  
       using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
       {
          bulkCopy.DestinationTableName = TheOnlineSQLTableName;

          try
          {
             // Write from the source to the destination.
             for (int colIndex = 0; colIndex < TheLocalDtToPush.Columns.Count; colIndex++)
             {
                bulkCopy.ColumnMappings.Add(colIndex, colIndex);
             }
             bulkCopy.WriteToServer(TheLocalDtToPush);
          }

          catch (Exception ex)
          {
             Console.WriteLine(ex.Message);
          }
       }

       // Perform a final count on the destination  
       // table to see how many rows were added. 
       long countEnd = System.Convert.ToInt32(
       commandRowCount.ExecuteScalar());

       retStrReport += string.Concat("Ending row count = ", countEnd, nl);
       retStrReport += string.Concat("==================================================", nl);
       retStrReport += string.Concat((countEnd - countStart)," rows were added.", nl);
       retStrReport += string.Concat("New Customers Was updated successfully", nl, "END OF PROCESS !");
       //Console.ReadLine();
       return retStrReport;
   }
}

Попытка его подключиться к SQL-серверу составляла около 7000 мс (в лучшем случае) и ~ 7700 мс в среднем. Также через случайную базу данных kv nosql заняло около 40 секунд (на самом деле я даже не записывал ее, когда она передавала x2 вариантов sql). Итак... есть ли более быстрый способ, чем то, что я тестировал в своем коде?

Изменить

Я использую win7 x64 8gb ram, и самое главное, я должен думать (как i5 3ghz) уже не так здорово x3 500Gb Wd на Raid-0 делает работу еще лучше но я просто говорю, если вы проверите свой компьютер хотя просто сравните его с любым другим способом в вашей конфигурации

Ответ 1

Вы пробовали SSIS? Я никогда не писал пакет SSIS с подключением loacldb, но это вид активности. SSIS должен хорошо подходить.

Если ваш источник данных является SQL Server, другой идеей будет создание связанного сервера. Не уверен, что это будет работать с localdb. Если вы можете настроить связанный сервер, вы можете обойти С# все вместе и загрузить свои данные с помощью инструкции INSERT.. SELECT... FROM... SQL.

Ответ 2

Удаление циклов... В SQL попытайтесь создать таблицу с 1 миллионом строк... и левое соединение это использует для вставки/выбора данных

Ответ 4

Если вы просто создаете бессмысленные данные, создайте хранимую процедуру и просто вызовите ее через .net

Если вы передаете реальные данные, повторная передача его в сохраненный процесс будет быстрее, но вам лучше отказаться от таблицы и воссоздать ее с помощью данных.

Если вы вставляете одну строку за раз, это займет больше времени, чем вставлять ее все сразу. Это займет еще больше времени, если у вас есть индексы для записи.

Ответ 5

вы можете использовать Dapper.NET. Dapper - это микро-ORM, выполняет запрос и сопоставляет результаты с строго типизированным списком. Объектно-реляционное сопоставление (ORM, O/RM и O/R mapping) в компьютерном программном обеспечении представляет собой метод программирования для преобразования данных между системами несовместимого типа в объектно-ориентированных языках программирования. Это создает, по сути, "базу данных виртуальных объектов", которая может использоваться из языка программирования

Для получения дополнительной информации:

проверить https://code.google.com/p/dapper-dot-net/

Репозиторий GitHub: https://github.com/SamSaffron/dapper-dot-net Надеюсь, это поможет.

Ответ 6

Создайте единый файл XML для всех строк, которые вы хотите сохранить в базе данных. Передайте эту хранимую процедуру XML в SQL и сохраните всю запись только в одном вызове. Но ваша хранимая процедура должна быть написана так, чтобы она могла читать все прочитанные, а затем вставлять в таблицу.

Ответ 7

Если это новый проект, я рекомендую вам использовать Entity Framework. В этом случае вы можете создать List < > с объектом со всеми необходимыми данными, а затем просто добавить его полностью в соответствующую таблицу. Таким образом, вы быстро получаете нужные данные и сразу отправляете их в базу данных.

Ответ 8

Я согласен с Mike в SSIS, но это не подходит для вашей среды, однако для процессов ETL, которые связаны с перекрестными вызовами на сервере и процессами обработки общих данных, это отличный встроенный инструмент и высоко интегрирован.

С 1 миллионом строк вам, вероятно, придется делать объемную вставку. В зависимости от размера строки вы не сможете использовать хранимую процедуру, если вы не сделали это в партиях. Заданная дата заполняет память довольно быстро, снова в зависимости от размера строки. Вы можете создать хранимую процедуру и получить тип таблицы и вызвать это каждое количество X строк, но почему бы нам это сделать, если у вас уже есть лучшее и масштабируемое решение. В следующем году этот миллион строк может составить 50 миллионов.

Я немного использовал SSIS, и если это организационная подгонка, я бы предложил посмотреть на нее, но это был бы не один раз ответ, не будет стоить зависимостей.