Gestão de Tamanhos de Lote de Cópias em Massa

Aplica-se a:SQL ServerBase de Dados SQL do AzureInstância Gerida do Azure SQLAzure Synapse Analytics

O principal objetivo de uma operação de cópia em lote em massa é definir o âmbito de uma transação. Se o tamanho do lote não estiver definido, as funções de cópia em massa consideram uma cópia em massa inteira como uma única transação. Se um tamanho de lote for definido, então cada lote constitui uma transação que é comprometida quando o lote termina.

Se for realizada uma cópia em massa sem tamanho de lote especificado e for encontrado um erro, toda a cópia em massa é revertida. A recuperação de uma cópia em massa de longa duração pode demorar muito tempo. Quando um tamanho de lote é definido, a cópia em massa considera cada lote uma transação e compromete cada batch. Se for encontrado um erro, apenas o último lote pendente precisa de ser revertido.

O tamanho do lote também pode afetar a sobrecarga de bloqueio. Ao realizar uma cópia em massa contra SQL Server, a dica TABLOCK pode ser especificada usando bcp_control para adquirir um bloqueio de tabela em vez de bloqueios de linha. O bloqueio de mesa único pode ser mantido com sobrecarga mínima durante toda uma operação de cópia em massa. Se o TABLOCK não for especificado, os bloqueios são mantidos em linhas individuais e a sobrecarga de manter todos os bloqueios durante a duração da cópia em massa pode abrandar o desempenho. Como os bloqueios só são mantidos durante a duração de uma transação, especificar um tamanho de lote resolve este problema ao gerar periodicamente um commit que liberta os bloqueios atualmente detidos.

O número de linhas que compõem um lote pode ter efeitos significativos de desempenho ao copiar em massa um grande número de linhas. As recomendações para o tamanho do lote dependem do tipo de cópia em massa que está a ser realizada.

  • Ao copiar em massa para o SQL Server, especifique a dica de cópia em massa do TABLOCK e defina um tamanho de lote grande.

  • Quando o TABLOCK não for especificado, limite o tamanho dos lotes a menos de 1.000 linhas.

Ao copiar em massa a partir de um ficheiro de dados, o tamanho do lote é especificado chamando bcp_control com a opção BCPBATCH antes de chamar bcp_exec. Ao copiar em massa de variáveis de programa usando bcp_bind e bcp_sendrow, o tamanho do lote é controlado ao chamar bcp_batch após chamar bcp_sendrowx vezes, onde x é o número de linhas num lote.

Para além de especificar o tamanho de uma transação, os lotes também afetam quando as linhas são enviadas através da rede para o servidor. As funções de cópia em massa normalmente armazenam em cache as linhas de bcp_sendrow até que um pacote de rede seja preenchido, e depois enviam o pacote completo para o servidor. No entanto, quando uma aplicação bcp_batch chama, o pacote atual é enviado para o servidor independentemente de ter sido preenchido ou não. Usar um tamanho de lote muito baixo pode abrandar o desempenho se resultar no envio de muitos pacotes parcialmente preenchidos para o servidor. Por exemplo, chamar bcp_batch após cada bcp_sendrow faz com que cada linha seja enviada num pacote separado e, a menos que as linhas sejam muito grandes, desperdiça espaço em cada pacote. O tamanho padrão dos pacotes de rede para SQL Server é 4 KB, embora uma aplicação possa alterar o tamanho chamando SQLSetConnectAttr especificando o atributo SQL_ATTR_PACKET_SIZE.

Outro efeito secundário dos lotes é que cada lote é considerado um conjunto de resultados excecional até ser concluído com bcp_batch. Se forem tentadas outras operações num handle de ligação enquanto um lote está pendente, o driver ODBC do SQL Server Native Client emite um erro com SQLState = "HY000" e uma cadeia de mensagens de erro de:

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