Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der Microsoft JDBC-Treiber für SQL Server ab Version 9.2 unterstützt die Verwendung der Bulk Copy-API für Batcheinfügevorgänge. Mit dieser Funktion können Benutzer den Treiber so aktivieren, dass er bei der Ausführung von Batcheinfügevorgängen im Hintergrund Bulk Copy-Vorgänge durchführt. Der Treiber strebt beim Einfügen derselben Daten eine bessere Leistung an, als der Treiber bei einem regulären Batcheinfügevorgang erzielen könnte. Der Treiber analysiert die SQL-Abfrage des Benutzers und nutzt anstelle des üblichen Batcheinfügevorgangs die API für das Massenkopieren. Im Folgenden werden verschiedene Möglichkeiten zur Aktivierung der Bulk Copy API für die Batcheinfügefunktion sowie ihre Einschränkungen aufgeführt. Diese Seite enthält außerdem ein kleines Codebeispiel, das eine Verwendung und die Leistungssteigerung veranschaulicht.
Dieses Feature ist nur auf die executeBatch() und executeLargeBatch()-APIs von PreparedStatement und CallableStatement anwendbar.
Voraussetzungen
Voraussetzung zum Aktivieren der Bulk Copy API für Stapeleinfügungen.
- Die Abfrage muss eine Einfügeabfrage sein (die Abfrage kann Kommentare enthalten, aber die Abfrage muss mit dem INSERT Schlüsselwort beginnen, damit dieses Feature wirksam wird).
Aktivierung der Massenkopier-API für Stapeleinfügungen
Es gibt drei Möglichkeiten, die Bulk Copy API für die Stapeleinfügung zu aktivieren.
1. Aktivieren über die Verbindungseigenschaft
Durch das Hinzufügen von useBulkCopyForBatchInsert=true; zur Verbindungszeichenfolge wird dieses Feature aktiviert.
Connection connection = DriverManager.getConnection("jdbc:sqlserver://<server>:<port>;userName=<user>;password=<password>;database=<database>;encrypt=true;useBulkCopyForBatchInsert=true;");
2. Aktivierung mit der setUseBulkCopyForBatchInsert()-Methode aus dem SQLServerConnection-Objekt
Durch den Aufruf von SQLServerConnection.setUseBulkCopyForBatchInsert(true) wird dieses Feature aktiviert.
SQLServerConnection.getUseBulkCopyForBatchInsert() ruft den aktuellen Wert für die Verbindungseigenschaft useBulkCopyForBatchInsert ab.
Der Wert für useBulkCopyForBatchInsert bleibt für jede PreparedStatement zum Zeitpunkt der Initialisierung konstant. Nachfolgende Aufrufe von SQLServerConnection.setUseBulkCopyForBatchInsert() haben keine Auswirkung auf den Wert des bereits erstellten PreparedStatement-Objekts.
3. Aktivierung mit der setUseBulkCopyForBatchInsert()-Methode aus dem SQLServerDataSource-Objekt
Die Vorgehensweise ähnelt der oben beschriebenen Option, zum Erstellen eines SQLServerConnection-Objekts wird jedoch SQLServerDataSource verwendet. Mit beiden Methoden werden die gleichen Ergebnisse erzielt.
Bekannte Einschränkungen
Für dieses Feature gelten aktuell die folgenden Einschränkungen.
- Einfügeabfragen, die nicht parametrisierte Werte enthalten (z. B.
INSERT INTO TABLE VALUES (?, 2), werden nicht unterstützt. Platzhalter (?) sind die einzigen unterstützten Parameter für diese Funktion. - Das Einfügen von Abfragen, die INSERT-SELECT-Ausdrücke enthalten (z. B.
INSERT INTO TABLE SELECT * FROM TABLE2), wird nicht unterstützt. - Einfügeabfragen, die mehrere VALUE-Ausdrücke enthalten (z. B.
INSERT INTO TABLE VALUES (1, 2) (3, 4)), werden nicht unterstützt. - INSERT-Abfragen, auf die eine OPTION-Klausel folgt, die mit mehreren Tabellen verknüpft sind oder auf die eine weitere Abfrage folgt, werden nicht unterstützt.
-
IDENTITY_INSERTwird nicht im Treiber verwaltet. Schließen Sie entweder keine Identitätsspalten in INSERT-Anweisungen ein, oder legen Sie denIDENTITY_INSERT-Zustand Ihrer Tabellen zwischen Anweisungen für Masseneinfügevorgänge manuell fest, oder übergeben Sie den expliziten Wert für eine Identitätsspalte manuell mit der Einfügeanweisung. Weitere Informationen finden Sie unter SET IDENTITY_INSERT. - Aufgrund der Einschränkungen der Massenkopie-API werden die Datentypen
MONEY,SMALLMONEY,DATE,DATETIME,DATETIMEOFFSET,SMALLDATETIME,TIME,GEOMETRYundGEOGRAPHYderzeit für dieses Feature in Azure SQL DW nicht unterstützt.
Wenn die Abfrage aufgrund von nicht SQL-Server-Instance-bezogenen Fehlern fehlschlägt, protokolliert der Treiber die Fehlermeldung und führt ein Fallback auf die ursprüngliche Logik für Masseneinfügevorgänge durch.
Beispiel
Dieses Beispiel demonstriert den Anwendungsfall eines Batch-Einfügevorgangs für tausend Zeilen, sowohl für reguläre Szenarien als auch für Szenarien mit der 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.");
}
}
Ergebnis:
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.
Siehe auch
Verbessern von Leistung und Zuverlässigkeit mit dem JDBC-Treiber