Есть ли какие-либо передовые методы определения верхних пределов частоты запуска INSERT? - PullRequest
0 голосов
/ 07 мая 2020

Приложение должно хранить данные в простой базе данных (вероятно, одна таблица, менее 10 полей). Данные собираются путем опроса удаленной службы примерно с частотой около 10 Гц, мы можем получить несколько строк в каждом опросе. супер-производительный, он не должен вызывать серьезного ухудшения работы других приложений или лишних ресурсов.

Как часто рекомендуется делать SQL INSERT? Разумны ли десятки или сотни INSERT в секунду, или это предпочтительнее пакетировать, может быть, один раз в секунду или каждые несколько секунд? Есть ли общие практики? БД не являются моей основной областью, поэтому накладные расходы на отдельные вызовы (c#) code-> DB (MS SQL) мне ничего не известно.

Ответы [ 3 ]

0 голосов
/ 07 мая 2020

Я бы порекомендовал вам следующие подходы, выраженные в псевдокоде:

Первый подход:

For each remote service polling
  start transaction
  if the number of rows < bulk copy threshold
     send all inserts in single batch
  otherwise
     bulk copy rows     
  end if
  commit transaction
end for

Порог массового копирования - это количество строк, из которых более эффективно использовать массовое копирование, чем пакет вставок.

для массового копирования строк существует специальный класс SqlBulkCopy , который является наиболее эффективным при вставке большого количества строк.

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

loop 
  while (batch.rows < batch size) and (time elapsed since last bulk copy < batch interval)
    add rows to batch from web service
  end while

  start transaction 
  bulk copy batch
  commit transaction
  clear batch
end loop

размер пакета и интервал пакета - числа, которые вам необходимо настроить.

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

Второй подход имеет большую задержку, однако он может обрабатывать гораздо больше строк.

Второй подход можно улучшить. Вместо ожидания заполнения пакета или истечения интервала для отправки данных на сервер SQL вы можете непрерывно отправлять строки в SqlBulkCopy. Это может быть достигнуто путем реализации IDataReader из удаленного опроса сервиса. У DataReader будет внутренний буфер (очередь), заполненный с момента последнего вызова удаленной веб-службы. По истечении интервала или достижении размера пакета и отсутствии строк в очереди DataReader.Read () возвращает false. Если в очереди больше нет строк, но интервал не истек или размер пакета не достигнут, DataReader снова вызывает удаленную веб-службу для заполнения внутренней очереди.

Это уточнение имеет некоторые преимущества:

  • Потребляйте гораздо меньше памяти. Вам не нужно хранить весь пакет в памяти, только внутреннюю очередь, всего несколько строк.
  • Он отправляет строки на SQL Сервер по мере их поступления. Вам не нужно ждать, чтобы заполнить пакет, чтобы отправить его на SQL сервер.
  • Он может обрабатывать больше строк в секунду.
0 голосов
/ 07 мая 2020

это скорее вопрос ваших потребностей, поскольку вам необходимо учитывать множество вариантов:

  1. вставка одной строки (генерировать накладные расходы)
  2. массовая вставка (в зависимости от ваших потребностей может не применимо)

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

Общая реализация, которую я выполняю:

  • массовая вставка во временную таблицу

  • обработка данных из временной таблицы в основная таблица в кусках по 1000 записей (вы можете протестировать производительность, которая зависит от производительности / использования сервера, но мои прошлые тесты дали лучший результат от 300 до 3.000 записей)

0 голосов
/ 07 мая 2020

В общем, выполнение insert в десять раз дороже, чем выполнение одной вставки для 10 строк. В основном есть две причины:

  • Существуют накладные расходы для каждой транзакции. 10 транзакций имеют 10-кратные накладные расходы.
  • Есть накладные расходы на выполнение запроса. 10x запросы имеют 10x накладные расходы. , SQL Сервер на разумном оборудовании должен уметь обрабатывать десятки и, возможно, сотни вставок в секунду. Если это соответствует требованиям вашего приложения, то их нельзя менять одновременно.

    Если это не так, вы можете начать работу над оптимизацией, например, кэшированием вставок на стороне приложения, чтобы вы могли выполнять вставки большего объема. Несомненно, на стороне приложения есть инструменты / библиотеки, которые могут в этом помочь. Однако Stack Overflow - не место для рекомендаций по инструментам.

...