Как вставить модели 1M в SQL

#c# #sql #.net

#c# #sql #.net

Вопрос:

У меня есть файл с 1 миллионом строк. Я читаю и вставляю эти строки в mssql. Операция чтения занимает около секунды, но вставка здесь работает не очень хорошо (Время: 00: 03: 36.1424842).

 public async Task<int> InsertAsync(List<Model> models)
{
    var _connectionString =
        "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=test;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False";
    var result = 0;
    try
    {
        using (var sqlBulk = new SqlBulkCopy(_connectionString))
        {
            sqlBulk.BatchSize = 10000;
            sqlBulk.DestinationTableName = "Counterparty";
            var dt = DataTableHelpers.ListToDataTable(models);
            sqlBulk.WriteToServer(dt);
        }
    }
    catch (Exception e)
    {
        _logger.Debug($"{e.Message} >>> {e.StackTrace}");
    }
    return resu<
}
 

Мои модели:

 public class Model
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Comment { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
    public bool IsActive { get; set; }
}
 

и строки файлов:

     TestIsert703,Comment694,Adress694,816,1
    TestIsert704,Comment695,Adress695,817,1
 

Я попытался изменить sqlBulk.Размер пакета, но у меня это не работает. Как я могу вставить с хорошей производительностью? Могу ли я как-то использовать parallel.for? Нагрузка на ноутбук составляет минимум 1 ГБ оперативной памяти, а процессы, как правило, протекают бесшумно.

Комментарии:

1. По моему опыту, выполнение этого внутри одной транзакции значительно ускоряет процесс (хотя я не знаю, почему или верно ли это для всех сценариев)

2. Обязательно ли это делать на C #? Вы могли бы использовать SSIS

3. Я бы сказал, это потому, что вы можете сохранить соединение открытым, а не открывать его снова и снова.

4. Держу пари, что большая часть времени уходит только на ListToDataTable() метод. Вы говорите, что использование процессора и оперативной памяти низкое, поэтому вам может быть намного лучше использовать некоторые асинхронные функции, чтобы использовать больше преимуществ этого оборудования.

5. @Joel Coehoorn можете ли вы объяснить или показать, как бы вы это сделали

Ответ №1:

Вы жалуетесь на то, что вставляете миллион записей за три с половиной минуты? Вы получаете более 4500 записей в секунду!

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

На стороне SQL Server вы можете улучшить эту работу, переключившись с ПОЛНОГО на ПРОСТОЙ (или даже МАССОВЫЙ) режим ведения журнала, но это не то, что я хотел бы делать постоянно. Я также вижу, что это локальная БД. Имеет ли SQL Server доступ к достаточному объему оперативной памяти в системе? Это может иметь огромное значение.

Комментарии:

1. Истекшее время преобразования моделей в datableTime: 00:00:02.2578097. доступно более 4 гигабайт оперативной памяти