Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Microsoft JDBC Driver per SQL Server versione 9.2 e successive supporta l'uso dell'API di copia bulk per le operazioni di inserimento batch. Con questa funzionalità gli utenti possono consentire al driver di eseguire operazioni di copia bulk sottostanti durante l'esecuzione di operazioni di inserimento batch. Il driver cerca di migliorare le prestazioni inserendo gli stessi dati che si avrebbero con una normale operazione di inserimento batch. Il driver analizza la query SQL dell'utente usando l'API di copia bulk invece della normale operazione di inserimento batch. Di seguito sono illustrati diversi modi per abilitare l'API di copia bulk per la funzionalità di inserimento batch e sono elencate le relative limitazioni. Questa pagina contiene un piccolo codice di esempio che illustra un utilizzo e anche l'aumento delle prestazioni.
Questa funzionalità è applicabile solo alle API executeBatch() e executeLargeBatch() di PreparedStatement e CallableStatement.
Prerequisiti
Prerequisito per l'abilitazione dell'API di copia bulk per l'inserimento batch.
- La query deve essere una query di inserimento (la query può contenere commenti, ma la query deve iniziare con la INSERT parola chiave affinché questa funzionalità venga applicata).
Abilitazione di API Bulk Copy per l'inserimento in batch
Sono disponibili tre modi per abilitare l'API di copia bulk per l'inserimento batch.
1. Attivazione tramite la proprietà di connessione
L'aggiunta di useBulkCopyForBatchInsert=true; alla stringa di connessione abilita questa funzionalità.
Connection connection = DriverManager.getConnection("jdbc:sqlserver://<server>:<port>;userName=<user>;password=<password>;database=<database>;encrypt=true;useBulkCopyForBatchInsert=true;");
2. Abilitazione con il metodo setUseBulkCopyForBatchInsert() dall'oggetto SQLServerConnection
La chiamata di SQLServerConnection. setUseBulkCopyForBatchInsert (true) consente di abilitare questa funzionalità.
SQLServerConnection.getUseBulkCopyForBatchInsert() consente di recuperare il valore corrente per la proprietà di connessione useBulkCopyForBatchInsert.
Il valore per useBulkCopyForBatchInsert rimane costante per ogni PreparedStatement al momento della sua inizializzazione. Qualsiasi chiamata successiva a SQLServerConnection.setUseBulkCopyForBatchInsert() non influirà sul valore di PreparedStatement già creato.
3. Abilitazione con il metodo setUseBulkCopyForBatchInsert() dall'oggetto SQLServerDataSource
Simile a quanto descritto sopra, ma con l'uso di SQLServerDataSource per creare un oggetto SQLServerConnection. Entrambi i metodi ottengono lo stesso risultato.
Limitazioni note
Al momento, questa funzionalità è soggetta alle limitazioni seguenti.
- Le query di inserimento contenenti valori senza parametri, ad esempio
INSERT INTO TABLE VALUES (?, 2), non sono supportate. I caratteri jolly (?) sono gli unici parametri consentiti per questa funzione. - Non sono supportate le query INSERT che contengono espressioni INSERTSELECT (ad esempio,
INSERT INTO TABLE SELECT * FROM TABLE2). - Le query di inserimento contenenti più espressioni VALUE, ad esempio
INSERT INTO TABLE VALUES (1, 2) (3, 4), non sono supportate. - Le query INSERT seguite dalla clausola OPTION, combinate con più tabelle o seguite da un'altra query non sono supportate.
-
IDENTITY_INSERTnon è gestito nel driver. O non includere le colonne Identity nelle istruzioni INSERT, oppure reimpostare manualmente lo statoIDENTITY_INSERTdelle tabelle tra un'istruzione INSERT batch e l'altra, oppure fornire manualmente il valore esplicito per una colonna Identity nell'istruzione INSERT. Per altre informazioni, vedere SET IDENTITY_INSERT. - A causa delle limitazioni dell'API Bulk Copy, i tipi di dati
MONEY,SMALLMONEY,DATE,DATETIME,DATETIMEOFFSET,SMALLDATETIME,TIME,GEOMETRYeGEOGRAPHYnon sono attualmente supportati per questa funzionalità con Azure SQL DW.
Se la query ha esito negativo a causa di errori non correlati all'istanza di SQL Server, il driver registra il messaggio di errore e torna alla logica originale per l'inserimento batch.
Esempio
Di seguito è riportato un esempio che illustra il caso d'uso per un'operazione di inserimento batch di un migliaio di righe, per entrambi gli scenari, normali e con API di copia bulk.
public static void main(String[] args) throws Exception
{
String tableName = "batchTest";
String tableNameBulkCopyAPI = "batchTestBulk";
String connectionUrl = "jdbc:sqlserver://<server>:<port>;encrypt=true;databaseName=<database>;user=<user>;password=<password>";
try (Connection con = DriverManager.getConnection(connectionUrl);
Statement stmt = con.createStatement();
PreparedStatement pstmt = con.prepareStatement("insert into " + tableName + " values (?, ?)");) {
String dropSql = "if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[" + tableName + "]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) DROP TABLE [" + tableName + "]";
stmt.execute(dropSql);
String createSql = "create table " + tableName + " (c1 int, c2 varchar(20))";
stmt.execute(createSql);
System.out.println("Starting batch operation using regular batch insert operation.");
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
pstmt.setInt(1, i);
pstmt.setString(2, "test" + i);
pstmt.addBatch();
}
pstmt.executeBatch();
long end = System.currentTimeMillis();
System.out.println("Finished. Time taken : " + (end - start) + " milliseconds.");
}
try (Connection con = DriverManager.getConnection(connectionUrl + ";useBulkCopyForBatchInsert=true");
Statement stmt = con.createStatement();
PreparedStatement pstmt = con.prepareStatement("insert into " + tableNameBulkCopyAPI + " values (?, ?)");) {
String dropSql = "if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[" + tableNameBulkCopyAPI + "]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) DROP TABLE [" + tableNameBulkCopyAPI + "]";
stmt.execute(dropSql);
String createSql = "create table " + tableNameBulkCopyAPI + " (c1 int, c2 varchar(20))";
stmt.execute(createSql);
System.out.println("Starting batch operation using Bulk Copy API.");
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
pstmt.setInt(1, i);
pstmt.setString(2, "test" + i);
pstmt.addBatch();
}
pstmt.executeBatch();
long end = System.currentTimeMillis();
System.out.println("Finished. Time taken : " + (end - start) + " milliseconds.");
}
}
Risultato:
Starting batch operation using regular batch insert operation.
Finished. Time taken : 104132 milliseconds.
Starting batch operation using Bulk Copy API.
Finished. Time taken : 1058 milliseconds.
Vedi anche
Uso del driver JDBC per il miglioramento di prestazioni e affidabilità