Compartilhar via


Gerenciando tamanhos de lote para cópia em massa

A principal finalidade de um lote em operações de cópia em massa é definir o escopo de uma transação. Se o tamanho de um lote não for definido, as funções de cópia em massa irão considerar uma cópia em massa inteira como uma única transação. Se o tamanho do lote for definido, cada lote constituirá uma transação que será confirmada quando o lote terminar.

Se uma cópia em massa for executada sem tamanho de lote especificado e um erro for retornado, a cópia em massa inteira será revertida. A recuperação de uma cópia em massa longa pode levar muito tempo. Quando um tamanho de lote é definido, a cópia em massa considera cada lote uma transação e confirma cada lote. Se um erro for encontrado, apenas o último lote pendente precisará ser revertido.

O tamanho do lote também pode afetar a sobrecarga de bloqueios. Ao executar uma operação de cópia em massa no SQL Server, você pode especificar a dica TABLOCK com bcp_control para obter um bloqueio de tabela em vez de bloqueios de linha. É possível manter um bloqueio de tabela com sobrecarga mínima para uma operação de cópia em massa inteira. Se TABLOCK não for especificada, os bloqueios serão mantidos em filas individuais e a sobrecarga da manutenção de todos os bloqueios durante a cópia em massa poderá prejudicar o desempenho. Pelo fato de os bloqueios só serem mantidos durante o tempo de uma transação, a especificação do tamanho de um lote trata esse problema gerando periodicamente uma confirmação que libera os bloqueios mantidos.

O número de linhas que compõem um lote pode ter efeitos significativos no desempenho quando a operação de cópia em massa é feita em um grande número de linhas. As recomendações de tamanho de lote dependem do tipo de cópia em massa que está sendo executada.

  • Ao fazer uma cópia em massa no SQL Server, especifique a dica de cópia em massa TABLOCK e defina um tamanho de lote grande.

  • Quando TABLOCK não é especificada, limite os tamanhos de lote para menos de 1.000 linhas.

Ao fazer uma cópia em massa de um arquivo de dados, o tamanho do lote é especificado chamando bcp_control com a opção de BCPBATCH antes de chamar bcp_exec. Quando você faz uma cópia em massa de variáveis de programa usando bcp_bind e bcp_sendrow, o tamanho de lote é controlado chamando bcp_batch depois de chamar bcp_sendrow x vezes, em que x é o número de linhas em um lote.

Além de especificar o tamanho de uma transação, os lotes também controlam quando serão enviadas linhas ao servidor através da rede. Em geral, as funções de cópia em massa armazenam em cache as linhas de bcp_sendrow até que um pacote de rede seja preenchido e, depois, envia o pacote cheio ao servidor. No entanto, quando um aplicativo chama bcp_batch, o pacote atual é enviado ao servidor independentemente de estar ou não preenchido. O uso de um tamanho de lote muito baixo pode prejudicar o desempenho se resultar no envio de muitos pacotes parcialmente preenchidos para o servidor. Por exemplo, chamar bcp_batch depois de cada bcp_sendrow faz com que cada linha seja enviada em um pacote separado e, a não ser que as linhas sejam muito largas, isso desperdiça o espaço em cada pacote. O tamanho padrão dos pacotes de rede do SQL Server é 4 KB, embora um aplicativo possa alterar esse tamanho chamando SQLSetConnectAttr ao especificar o atributo SQL_ATTR_PACKET_SIZE.

Outro efeito colateral do uso de lotes é que cada lote é considerado um conjunto de resultados pendentes até que seja completado com bcp_batch. Se qualquer outra operação for tentada em um identificador de conexão enquanto um lote estiver pendente, o driver ODBC do SQL Server Native Client emitirá um erro com SQLState = "HY000" e a seguinte mensagem de erro:

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