Gestione delle dimensioni dei batch di copia bulk

Lo scopo principale di un batch nelle operazioni di copia bulk è definire l'ambito di una transazione. Se non si impostano le dimensioni del batch, le funzioni di copia bulk considerano un'intera copia bulk come una transazione. Se le dimensioni del batch vengono impostate, ogni batch rappresenterà una transazione di cui verrà eseguito il commit alla fine dell'esecuzione.

Se una copia bulk viene eseguita senza specificare le dimensioni del batch e si verifica un errore, viene eseguito il rollback dell'intera copia bulk. Il recupero di una copia bulk con esecuzione prolungata può richiedere molto tempo. Quando vengono impostate le dimensioni di un batch, la copia bulk considera ogni batch come una singola transazione e ne esegue il commit. Se si verifica un errore, è necessario eseguire il rollback solo dell'ultimo batch in attesa.

Le dimensioni del batch possono influire anche sull'overhead dei blocchi. Quando si esegue una copia bulk in SQL Server, è possibile specificare l'hint TABLOCK utilizzando bcp_control per acquisire un blocco di tabella anziché blocchi di riga. Il singolo blocco di tabella può essere gestito con un overhead minimo per un'operazione di copia bulk intera. Se TABLOCK non viene specificato, i blocchi vengono gestiti su righe singole e l'overhead della gestione di tutti i blocchi per la durata della copia bulk può rallentare le prestazioni. Poiché i blocchi vengono gestiti solo per la durata di una transazione, la specifica delle dimensioni del batch risolve il problema grazie alla generazione periodica di un commit che libera i blocchi attualmente gestiti.

Il numero di righe che costituiscono un batch può avere effetti significativi sulle prestazioni quando si esegue la copia bulk di un gran numero di righe. I requisiti per le dimensioni del batch dipendono dal tipo di copia bulk eseguita.

  • Quando si esegue la copia bulk in SQL Server, specificare l'hint di copia bulk TABLOCK e impostare le dimensioni del batch su un valore grande.

  • Quando TABLOCK non viene specificato, impostare le dimensioni del batch su un valore che non superi 1.000 righe.

Quando si esegue la copia bulk da un file di dati, le dimensioni del batch vengono specificate chiamando bcp_control con l'opzione BCPBATCH prima di chiamare bcp_exec. Quando si esegue la copia bulk da variabili del programma utilizzando bcp_bind e bcp_sendrow, le dimensioni del batch vengono controllate chiamando bcp_batch dopo avere chiamato bcp_sendrow x volte, dove x è il numero di righe di un batch.

Oltre a specificare le dimensioni di una transazione, i batch influiscono anche sull'invio in rete delle righe al server. In genere, le funzioni di copia bulk memorizzano nella cache le righe di bcp_sendrow fino a quando non viene riempito un pacchetto di rete, quindi inviano il pacchetto completo al server. Quando tuttavia un'applicazione chiama bcp_batch, il pacchetto corrente viene inviato al server indipendentemente dal relativo riempimento. L'utilizzo di dimensioni del batch molto ridotte può rallentare le prestazioni se determina l'invio al server di più pacchetti riempiti parzialmente. La chiamata a bcp_batch dopo ogni bcp_sendrow determina ad esempio l'invio di ogni riga in un pacchetto separato e, a meno che le righe non siano molto grandi, una perdita di spazio in ogni pacchetto. Le dimensioni predefinite dei pacchetti di rete per SQL Server corrispondono a 4 KB, anche se un'applicazione può modificarle chiamando SQLSetConnectAttr che specifica l'attributo SQL_ATTR_PACKET_SIZE.

Un altro effetto collaterale dei batch consiste nel fatto che ogni batch viene considerato come set di risultati in attesa fino a quando non viene completato con bcp_batch. Se si tenta qualsiasi altra operazione in un handle di connessione mentre un batch è in attesa, il driver ODBC di SQL Server Native Client genera un errore con l'identificatore SQLState = "HY000" e la stringa del messaggio di errore seguente:

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