Оптимизация производительности массивной вставки ...? - PullRequest
5 голосов
/ 10 января 2011

Дано: SQL Server 2008 R2. Закройте некоторые диски с данными о скорости. Журнал дисков отстает.

Обязательно: МНОГО МНОГО МНОГО МНОГО вкладышей. Как от 10.000 до 30.000 строк в простую таблицу с двумя индексами в секунду. Вставки имеют внутренний порядок и не будут повторяться, так как такой порядок вставок не должен поддерживаться в краткосрочной перспективе (то есть несколько параллельных вставок в порядке).

Пока: накопление данных в очереди. Регулярно (асинхронный пул потоков) очищает до 1024 записей в рабочем элементе, который попадает в очередь. Threadpool (пользовательский класс) имеет 32 возможных потока. Открывает 32 соединения.

Проблема: производительность снижается с коэффициентом 300 .... вставляется только от 100 до 150 строк в секунду. Время ожидания журнала составляет до 40% - 45% времени обработки (мс в секунду) на сервере sql. Низкая загрузка ЦП сервера (от 4% до 5% или около того).

Не используется: массовая вставка. Данные должны быть записаны на диск в режиме реального времени. Это в значительной степени процесс архивации данных, проходящих через систему, но есть запросы, которым требуется регулярный доступ к данным. Я мог бы попытаться записать их на диск и использовать массовую загрузку 1-2 раза в секунду ... попробую.

Кто-нибудь умная идея? Мой следующий шаг - переместить журнал в набор быстрых дисков (128 ГБ современный ssd) и посмотреть, что произойдет потом. Значительное повышение производительности, вероятно, изменит ситуацию. Но даже тогда ... вопрос в том, возможно ли это.

Так что, пожалуйста, используйте умные идеи.

Ответы [ 3 ]

4 голосов
/ 10 января 2011

Хорошо, что угодно, сам.Давайте попробуем SqlBulkCopy, выполняя пакетирование до 65536 записей и сбрасывая их каждую секунду асинхронно.Сообщит о достижениях.

3 голосов
/ 10 февраля 2011

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

  • Разделение журнала и файла dbf на разные наборы шпинделей
  • Использовать базовое восстановление
  • вы не упомянули никаких требований к индексации, кроме того факта, что порядок вставок не важен - в этом случае кластерные индексы для чего-либо, кроме столбца идентификаторов, не должны использоваться.
  • снова начните масштабирование параллелизма с 1 и остановитесь, когда производительность упадет; что-нибудь из этого может повредить производительности.
  • вместо переноса на диск в bcp, и, поскольку вы используете SQL Server 2008, рассмотрите возможность вставки нескольких строк одновременно; этот оператор вставляет три строки в одном вызове sql

    ВСТАВИТЬ В СТОЛИЧНЫЕ ЗНАЧЕНИЯ (1,2,3), (4,5,6), (7,8,9)

Я занимал около 500 различных вставок в секунду из одного потока. После исключения сети и ЦП (0 как на клиенте, так и на сервере) я предположил, что виноват диск io на сервере, однако при вставке из трех пакетов получилось 1500 вставок в секунду, что исключает дисковый ввод-вывод.

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

Пакетирование таким образом, ожидание x событий, которые будут получены перед вызовом insert, теперь позволяет мне вставлять со скоростью ~ 2700 вставок в секунду из одного потока, который, как представляется, является верхним пределом для моей конфигурации.

Примечание: если у вас нет постоянного потока событий, поступающих постоянно, вы можете подумать о добавлении таймера, который сбрасывает ваши вставки через определенный период времени (чтобы вы видели последнее событие дня!)

1 голос
/ 09 октября 2011

Некоторые предложения по увеличению производительности вставки:

  • Увеличение размера пакета ADO.NET
  • Выбор кластеризованного индекса целевой таблицы разумно, чтобы вставки не приводили к расщеплению узлов кластеризованного индекса(например, столбец autoinc)
  • Сначала вставьте во временную таблицу кучи, а затем выполните один большой оператор "вставка по выбору", чтобы поместить все эти данные промежуточной таблицы в фактическую целевую таблицу
  • ApplySqlBulkCopy
  • Выберите модель восстановления «Bulk Logged» вместо модели «Full» восстановления
  • Установите блокировку таблицы перед вставкой (если это позволяет ваш бизнес-сценарий)

Взято из Советы по молниеносной производительности вставки на SqlServer

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...