Användning av masskopierings API för batchinmatningsoperation
Microsoft JDBC-drivrutinen för SQL Server version 9.2 och senare stöder användning av Bulk Copy API för batchinfogningsåtgärder. Med den här funktionen kan användare göra det möjligt för drivrutinen att utföra masskopieringsåtgärder under när batchinfogningsåtgärder körs. Drivrutinen syftar till att uppnå förbättrad prestanda genom att infoga samma data som drivrutinen skulle göra med vanlig batchinfogning. Drivrutinen analyserar användarens SQL-fråga med hjälp av Bulk Copy API istället för den vanliga batchinfogningsåtgärden. Följande inställningar är olika sätt att aktivera masskopierings-API:et för batchinfogningsfunktionen och visar en lista över dess begränsningar. Den här sidan innehåller också en liten exempelkod som visar en användning och prestandaökningen.
Den här funktionen gäller endast för Api:er för PreparedStatement och CallableStatement executeBatch()
& executeLargeBatch()
.
Förutsättningar
Krav för att aktivera MASSkopierings-API för batchinfogning.
- Frågan måste vara en insert-fråga (frågan kan innehålla kommentarer, men frågan måste börja med nyckelordet INSERT för att den här funktionen ska träda i kraft).
Aktivera masskopierings-API för batchinfogning
Det finns tre sätt att slå på Bulk Copy API för batchinfogning.
1. Aktivera genom anslutningsegenskap
Om du lägger till useBulkCopyForBatchInsert=true;
i anslutningssträngen aktiveras den här funktionen.
Connection connection = DriverManager.getConnection("jdbc:sqlserver://<server>:<port>;userName=<user>;password=<password>;database=<database>;encrypt=true;useBulkCopyForBatchInsert=true;");
2. Aktivera med metoden setUseBulkCopyForBatchInsert() från SQLServerConnection-objektet
Genom att anropa SQLServerConnection.setUseBulkCopyForBatchInsert(true) aktiveras den här funktionen.
SQLServerConnection.getUseBulkCopyForBatchInsert() hämtar det aktuella värdet för useBulkCopyForBatchInsert anslutningsegenskap.
Värdet för useBulkCopyForBatchInsert förblir konstant för varje PreparedStatement vid tidpunkten för initieringen. Efterföljande anrop till SQLServerConnection.setUseBulkCopyForBatchInsert() påverkar inte det redan skapade Värdet för PreparedStatement.
3. Aktivera med metoden setUseBulkCopyForBatchInsert() från SQLServerDataSource-objektet
Liknar föregående alternativ, men använder SQLServerDataSource för att skapa ett SQLServerConnection-objekt. Båda metoderna uppnår samma resultat.
Kända begränsningar
Det finns för närvarande dessa begränsningar som gäller för den här funktionen.
- Infoga frågor som innehåller icke-parametriserade värden (till exempel
INSERT INTO TABLE VALUES (?, 2
)) stöds inte. Jokertecken (?) är de enda parametrar som stöds för den här funktionen. - Infoga frågor som innehåller INSERT-SELECT uttryck (till exempel
INSERT INTO TABLE SELECT * FROM TABLE2
), stöds inte. - Infoga frågor som innehåller flera VALUE-uttryck (till exempel
INSERT INTO TABLE VALUES (1, 2) (3, 4)
), stöds inte. - Infoga frågor som följs av OPTION-satsen, som är ansluten till flera tabeller eller följt av en annan fråga, stöds inte.
-
IDENTITY_INSERT
hanteras inte i drivrutinen. Ta antingen inte med identitetskolumner i insert-instruktionerna, ange manuelltIDENTITY_INSERT
-tillståndet för dina tabeller mellan batch-insert-instruktioner, eller ange manuellt det explicita värdet för en identitetskolumn i insert-instruktionen. Mer information finns i SET IDENTITY_INSERT. - På grund av begränsningarna i API för masskopiering stöds
MONEY
,SMALLMONEY
,DATE
,DATETIME
,DATETIMEOFFSET
,SMALLDATETIME
,TIME
,GEOMETRY
ochGEOGRAPHY
datatyper för närvarande inte för den här funktionen.
Om frågan misslyckas på grund av fel som inte är relaterade till SQL Server-instansen loggar drivrutinen felmeddelandet och återgår till den ursprungliga logiken för batchinfogning.
Exempel
Det här exemplet visar användningsfallet för en batchinfogningsåtgärd på tusen rader, för både vanliga och masskopierings-API-scenarier.
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.");
}
}
Resultat:
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.
Se även
Förbättra prestanda och tillförlitlighet med JDBC-drivrutinen