Управление размером пакета массового копирования

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

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

Размер пакета может также влиять на затраты ресурсов, связанные с управлением блокировками. При выполнении массового копирования на SQL Server можно задать подсказку TABLOCK с помощью bcp_control, чтобы получить блокировку таблицы вместо блокировок строк. Минимальные издержки всей операции массового копирования может дать одна блокировка таблицы. Если подсказка TABLOCK не указана, тогда выполняются блокировки для отдельных строк, и издержки обслуживания всех блокировок во время массового копирования могут уменьшить производительность. Поскольку блокировки удерживаются только во время транзакции, указание размера пакета обращается к этой проблеме, регулярно формируя фиксацию, которая освобождает текущие блокировки.

Количество строк в пакете может значительно повлиять на производительность при массовом копировании большого числа строк. Рекомендации, касающиеся размера пакета, зависят от типа выполняемого массового копирования.

  • При массовом копировании в SQL Server укажите подсказку TABLOCK и задайте большой размер пакета.

  • Если подсказка TABLOCK не задана, ограничьте размер пакета числом менее 1000 строк.

При массовом копировании из файла данных размер пакета указывается при вызове bcp_control с параметром BCPBATCH, потом вызывается bcp_exec. При массовом копировании из переменных программы с использованием bcp_bind и bcp_sendrow управление размером пакета осуществляется путем вызова bcp_batch после x-кратного вызова  bcp_sendrow, где x — это количество строк в пакете.

Помимо указания размера транзакции, пакеты также оказывают влияние при отправке строк по сети серверу. Функции массового копирования обычно кэшируют строки из bcp_sendrow до тех пор, пока сетевой пакет не заполняется, а потом отправляют на сервер полный пакет. Если приложение вызывает bcp_batch, то текущий пакет отправляется на сервер вне зависимости от того, был ли он заполнен. Использование очень маленького размера пакета может снизить производительность, если оно приведет к к отправке на сервер большого числа частично заполненных пакетов. Например, вызов bcp_batch после каждого bcp_sendrow приведет к отправке каждой строки в отдельном пакете, и, если только строки не очень большие, в каждом пакете не полностью используется пространство. Размер по умолчанию сетевого пакета для SQL Server равен 4 КБ, хотя приложение может изменить размер, вызвав SQLSetConnectAttr с атрибутом SQL_ATTR_PACKET_SIZE.

Другой побочный эффект пакетов заключается в том, что каждый пакет рассматривается как невыполненный результирующий набор до тех пор, пока он не завершается bcp_batch. Во время ожидания выполнения пакета при попытке выполнить другие операции в обработчике соединений драйвер ODBC собственного клиента SQL Server выдает ошибку с SQLState = "HY000" и строкой сообщения об ошибке:

"[Microsoft][SQL Server Native Client] Connection is busy withresults for another hstmt."