Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O Microsoft JDBC Driver para SQL Server versão 9.2 e posterior é compatível com o uso de uma API de Cópia em Massa para executar operações de inserção de lote. Esse recurso permite que os usuários configurem o driver para realizar operações de cópia em massa internamente ao executar operações de inserção em lote. O driver tem como objetivo melhorar o desempenho ao inserir os mesmos dados que inseriria com uma operação normal de inserção em lote. O driver analisa a consulta SQL do usuário, usando a API de cópia em massa em vez da operação usual de inserção em lote. As configurações a seguir são vários modos de habilitar uma API de Cópia em Massa para obter um recurso de inserção de lote, bem como listam as respectivas limitações. Essa página também contém um pequeno código de exemplo que demonstra um uso e o aumento de desempenho também.
Esse recurso só é aplicável a APIs executeBatch() e executeLargeBatch() de PreparedStatement e CallableStatement.
Pré-requisitos
Pré-requisito para habilitar a Bulk Copy API para inserção em lote.
- A consulta deve ser uma consulta de inserção (a consulta pode conter comentários, mas a consulta deve começar com a INSERT palavra-chave para que esse recurso entre em vigor).
Como habilitar a API de cópia em massa para inserção em lote
Há três maneiras de habilitar a API de Cópia em Massa para inserção em lote.
1. Como habilitar com a propriedade de conexão
Adicionar useBulkCopyForBatchInsert=true; à cadeia de conexão habilita esse recurso.
Connection connection = DriverManager.getConnection("jdbc:sqlserver://<server>:<port>;userName=<user>;password=<password>;database=<database>;encrypt=true;useBulkCopyForBatchInsert=true;");
2. Como habilitar com o método setUseBulkCopyForBatchInsert() do objeto SQLServerConnection
Chamar SQLServerConnection.setUseBulkCopyForBatchInsert(true) habilita esse recurso.
SQLServerConnection.getUseBulkCopyForBatchInsert() recupera o valor atual da propriedade de conexão useBulkCopyForBatchInsert.
O valor de useBulkCopyForBatchInsert permanece constante para cada PreparedStatement no momento da inicialização. Chamadas subsequentes a SQLServerConnection.setUseBulkCopyForBatchInsert() não afetarão o valor de PreparedStatement criado anteriormente.
3. Como habilitar com o método setUseBulkCopyForBatchInsert() do objeto SQLServerDataSource
Semelhante à opção anterior, mas usando SQLServerDataSource para criar um objeto SQLServerConnection. Ambos os métodos geram o mesmo resultado.
Limitações conhecidas
No momento, há essas limitações aplicáveis a esse recurso.
- Não há suporte para consultas de inserção que contenham valores não parametrizados (por exemplo,
INSERT INTO TABLE VALUES (?, 2). Curingas (?) são os únicos parâmetros aceitos por essa função. - Não há suporte para a inserção de consultas que contêm expressões INSERTSELECT (por exemplo,
INSERT INTO TABLE SELECT * FROM TABLE2). - Não há suporte para consultas de inserção que contenham múltiplas expressões VALUE (por exemplo,
INSERT INTO TABLE VALUES (1, 2) (3, 4)). - Não há suporte para consultas de inserção que sejam seguidas pela cláusula OPTION, associadas a várias tabelas ou seguidas por outra consulta.
-
IDENTITY_INSERTnão é gerenciado no driver. Não inclua colunas de identidade em instruções INSERT, defina manualmente o estadoIDENTITY_INSERTde suas tabelas entre instruções INSERT em lote ou forneça explicitamente o valor de uma coluna de identidade na instrução INSERT. Para obter mais informações, consulte SET IDENTITY_INSERT. - Devido às limitações da API de Cópia em Massa, os tipos de dados
MONEY,SMALLMONEY,DATE,DATETIME,DATETIMEOFFSET,SMALLDATETIME,TIME,GEOMETRYeGEOGRAPHYatualmente não são suportados por este recurso no SQL do Azure Data Warehouse.
Se a consulta falhar devido a erros não relacionados à instância do SQL Server, o driver registrará a mensagem de erro em log e retornará à lógica original de inserção em lote.
Exemplo
Este exemplo demonstra o cenário de uso de uma operação de inserção em lote de mil linhas, tanto para cenários regulares quanto para cenários com a Bulk Copy API.
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.");
}
}
Resultado:
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.
Confira também
Melhorando o desempenho e a confiabilidade com o JDBC Driver