Управление размером пакета массового копирования
Основным назначением пакета в операциях массового копирования является определение области транзакции. Если размер пакета не задан, то функции массового копирования рассматривают все массовое копирование как единую транзакцию. Если указан размер пакета, каждый пакет представляет собой транзакцию, которая фиксируется после завершения работы пакета.
Если при выполнении массового копирования размер пакета не указан и возникает ошибка, то происходит откат всего массового копирования. Восстановление массового копирования с продолжительным временем выполнения может занять значительное время. Если размер пакета задан, массовое копирование рассматривает каждый пакет как транзакцию и фиксирует каждый пакет. Если происходит ошибка, то необходим откат только одного последнего необработанного пакета.
Размер пакета может также влиять на затраты ресурсов, связанные с управлением блокировками. При выполнении массового копирования на 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 with
results for another hstmt."