2017-01-16 3 views
0

Я использую Dapper для вставки данных из канала реального времени в Sql Server, поэтому я забочусь о производительности. Недавно я заметил что-то странное.
Из коробки, если вы дадите Dapper коллекцию и запрос вставки, она вызывает инструкции вставки для каждого элемента. Мои тесты показывают, что я могу вставить примерно 1800 объектов с 12 полями за 1 секунду таким образом (подсчитывая только connection.Execute(...) времени работы.
Теперь я не нашел функциональность пакетной вставки в Dapper и реализовал свой собственный (построение списка параметров и sql-запроса), После чего я обнаружил, что могу вставить только одну партию примерно через 3 секунды (что ограничено 1000 строками) (опять же, только подсчет звонков.
Итак, это делает мою доработку почти в 6 раз медленнее чем отправка каждая строка в отдельном запросе.Может ли кто-нибудь объяснить это мне? Я думал, что люди используют пакетные операции для ускорения процесса.
Я бы хотел, чтобы время вставки было не более 1 секунды. Я использую Sql Server 2012 Standard, которыйв локальной сети. Таблица, в которую я вставляю, имеет только кластеризованный индекс для первичного ключа (который является полем bigint), некластеризованных индексов и триггеров.
Я могу опубликовать код, но там действительно ничего особенногоМассовая вставка через Dapper медленнее, чем вставка строк один за другим

+0

В чем проблема? 1 секунда для вставки слишком долго? Вы недовольны по одному вставке? В обоих случаях, почему?Есть преимущества как по одному, так и для массовой вставки в зависимости от среды и использования. Кроме того, это один или повторяющийся, и вы абсолютно * имеете * использовать Dapper? – iamdave

+0

@iamdave проблема в том, что мне нужно вставить больше данных, которые сходит с канала в реальном времени. Сейчас я использую Dapper, и он работает примерно на 30% объема, который я планирую использовать для производства. Нет, это не должно быть Dapper, я не пробовал SqlBulkCopy еще – chester89

+1

Возможно, стоит взглянуть на вашу собственную реализацию пакетной вставки. – grek40

ответ

2

Я не уверен, почему вы используете метод расширения Dapper Execute, если вы хотите получить лучшую производительность.

Лучший бесплатный способ вставки с наилучшей производительностью - непосредственно использовать класс SqlBulkCopy.

Отказ от ответственности: Я владелец проекта Dapper Plus

Этот проект обеспечивает легкий поддержку для следующих операций:

  • BulkInsert
  • BulkUpdate
  • BulkDelete
  • BulkMerge

Пример:

// CONFIGURE & MAP entity 
DapperPlusManager.Entity<Order>() 
       .Table("Orders") 
       .Identity(x => x.ID); 

// CHAIN & SAVE entity 
connection.BulkInsert(orders) 
      .AlsoInsert(order => order.Items); 
      .Include(x => x.ThenMerge(order => order.Invoice) 
         .AlsoMerge(invoice => invoice.Items)) 
      .AlsoMerge(x => x.ShippingAddress); 
0

Идеального размер пакета может варьироваться от сервера к серверу, ключевой фактор Logging, это повлияет как ресурсоемкий Вкладыш и насколько велики вы можете сделать свою партию, прежде чем вы видите падение производительности.

Ключ к быстрым вставкам/обновлениям гарантирует, что вы отвечаете требованиям минимальной регистрации, пожалуйста, ознакомьтесь с этим Microsoft White Paper. Не паникуйте - вам не нужно все это читать - посмотрите на таблицу, описывающую условия для соответствия минимальной регистрации (вам нужно поговорить с вашим администратором баз данных).

Как только вы получили как можно меньше регистраций, вам нужно взглянуть на планы выполнения для SPOOLS, если партия начинает наматываться на Tempdb, тогда вы столкнетесь с резким замедлением. Ключ должен держать пакет достаточно малым, чтобы оставаться в буфере (ОЗУ). Но объем доступного буферного пространства будет зависеть от других процессов.

Примечание: TABLOCK - это не то же самое, что TABLOCKX.

+0

будет изучать его. честно говоря, я уже использовал SqlBulkCopy, и он работает быстрее всех альтернатив. Я могу вставить 1500 строк менее чем за 100 мс. мне более чем достаточно – chester89

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