Как установить для DataAdapter.UpdateBatchSize «оптимальное» значение? - PullRequest
6 голосов
/ 25 августа 2010

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

Я вставляю 160k строк в таблицу, и среднее время для моих проверенных значений составляет 115+/ - 2 сек.Без пакетирования это занимает 210 секунд, поэтому я вполне доволен улучшением.Целевая таблица:

CREATE TABLE [dbo].[p_DataIdeas](
    [wave] [int] NOT NULL,
    [idnumber] [int] NOT NULL,
    [ideaID] [int] NOT NULL,
    [haveSeen] [bit] NOT NULL CONSTRAINT [DF_p_DataIdeas_haveSeen]  DEFAULT ((0)),
  CONSTRAINT [PK_p_DataIdeas] PRIMARY KEY CLUSTERED 
(
  [wave] ASC,
  [idnumber] ASC,
  [ideaID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON
) ON [PRIMARY]
) ON [PRIMARY]

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

Есть ли что-нибудь лучшее?практики, которые кто-то может порекомендовать?

Ответы [ 3 ]

6 голосов
/ 02 декабря 2011

Эффект пакетирования можно увидеть, посмотрев на SQL Profiler или вызвав SqlConnection.RetrieveStatistics(). То, что вы должны увидеть, - это то, что каждая партия соответствует одному обращению к базе данных.

Что касается того, как оптимизировать размер пакета, очень грубое правило заключается в том, что производительность, как правило, перестает улучшаться при размерах пакета выше 50 - фактически, иногда большие партии могут работать медленнее, чем меньшие. Если я слишком занят, чтобы тестировать, я обычно начинаю с пакета из 20 (если я не использую табличные параметры, где пакеты до 500 могут быть быстрее, чем меньшие). Однако оптимальное количество зависит от таких факторов, как общий размер вставок (все они будут помещаться в ОЗУ), скорость диска, на котором расположен журнал вашей БД, находится ли журнал на отдельном диске / LUN ( большая стоимость, если это не так) и т. д.

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

Первым шагом в улучшении производительности ваших вставок будет выполнение их в транзакциях - возможно, по одной транзакции в каждом пакете или двух. Помимо этого, табличными параметрами, вероятно, является следующий шаг, использующий хранимую процедуру с INSERT INTO Table SELECT column FROM @TableArgument.

1 голос
/ 03 декабря 2011

Хотя изменение UpdateBatchSize в некоторой степени поможет, базовый подход к использованию DataAdapter для обновления большого количества записей будет медленным. Это связано с тем, что в конечном итоге DataAdapter будет генерировать отдельный оператор SQL (вставка, обновление или удаление) для каждой строки. UpdateBatchSize влияет только на то, сколько из этих отдельных операторов отправляется в одном пакете TSQL при отправке на SQL Server.

Чтобы значительно повысить производительность, вы хотите, чтобы SQLServer вставлял / обновлял / удалял много записей в одном операторе (обычно с использованием какого-либо типа JOIN). Табличные значения параметров (как упомянуто RickNZ) - один из способов сделать это. Другой возможностью является использование SqlBulkCopy (хотя для этого вам обычно потребуется промежуточная таблица).

0 голосов
/ 11 июня 2015

Убедитесь, что есть активная транзакция, которая значительно улучшит производительность (примерно в 30 раз в моих тестах с использованием MysqlDataAdapter).

...