Toplu ekleme işlemi için toplu kopyalama API'sini kullanma
JDBC sürücüsünü indirin
SQL Server sürüm 9.2 ve üzeri için Microsoft JDBC Sürücüsü, toplu ekleme işlemleri için Toplu Kopyalama API'sinin kullanılmasını destekler. Bu özellik, kullanıcıların toplu ekleme işlemleri yürütürken sürücünün Toplu Kopyalama işlemlerini gerçekleştirmesini etkinleştirmesine olanak tanır. Sürücü, normal toplu ekleme işlemi sırasında ekleyeceği verilerle aynı verileri eklerken performansı artırmayı amaçlar. Sürücü, kullanıcının SQL Sorgusunu ayrıştırarak normal toplu ekleme işlemi yerine Toplu Kopyalama API'sini kullanır. Aşağıdaki ayarlar toplu ekleme özelliği için Toplu Kopyalama API'sini etkinleştirmenin çeşitli yollarıdır ve sınırlamalarını listeler. Bu sayfa ayrıca kullanımı ve performans artışını gösteren küçük bir örnek kod içerir.
Bu özellik yalnızca PreparedStatement ve CallableStatement'ın executeBatch()
& executeLargeBatch()
API'leri için geçerlidir.
Önkoşullar
Toplu ekleme için Toplu Kopyalama API'sini etkinleştirme önkoşulu.
- Sorgu bir ekleme sorgusu olmalıdır (sorgu açıklama içerebilir, ancak bu özelliğin etkili olması için sorgu INSERT anahtar sözcüğüyle başlamalıdır).
Toplu ekleme için toplu kopyalama API'sini etkinleştirme
Toplu ekleme için Toplu Kopyalama API'sini etkinleştirmenin üç yolu vardır.
1. Bağlantı özelliğiyle etkinleştirme
Bağlantı dizesine useBulkCopyForBatchInsert=true;
eklemek bu özelliği etkinleştirir.
Connection connection = DriverManager.getConnection("jdbc:sqlserver://<server>:<port>;userName=<user>;password=<password>;database=<database>;encrypt=true;useBulkCopyForBatchInsert=true;");
2. SQLServerConnection nesnesinden setUseBulkCopyForBatchInsert() yöntemiyle etkinleştirme
SQLServerConnection.setUseBulkCopyForBatchInsert(true) çağrısı bu özelliği etkinleştirir.
SQLServerConnection.getUseBulkCopyForBatchInsert()useBulkCopyForBatchInsert bağlantı özelliği için geçerli değeri alır.
useBulkCopyForBatchInsert değeri, her PreparedStatement için başlatma anında sabit kalır. SQLServerConnection.setUseBulkCopyForBatchInsert() sonraki çağrılar, önceden oluşturulmuş PreparedStatement değerini etkilemez.
3. SQLServerDataSource nesnesinden setUseBulkCopyForBatchInsert() yöntemiyle etkinleştirme
Önceki seçeneğe benzer, ancak SQLServerConnection nesnesi oluşturmak için SQLServerDataSource kullanma. Her iki yöntem de aynı sonucu elde eder.
Bilinen sınırlamalar
Şu anda bu özellik için geçerli olan bu sınırlamalar vardır.
- Parametrelenmemiş değerler (örneğin,
INSERT INTO TABLE VALUES (?, 2
) içeren sorgular eklemek desteklenmez. Joker karakterler (?) bu işlev için desteklenen tek parametrelerdir. - INSERT-SELECT ifadeleri içeren sorgular ekleme (örneğin,
INSERT INTO TABLE SELECT * FROM TABLE2
), desteklenmez. - Birden çok VALUE ifadesi içeren sorgular ekleme (örneğin,
INSERT INTO TABLE VALUES (1, 2) (3, 4)
), desteklenmez. - OPTION yan tümcesi tarafından takip edilen, birden çok tabloyla birleştirilen veya ardından başka bir sorgu gelen sorguları ekleme desteklenmez.
-
IDENTITY_INSERT
sürücü tarafından yönetilmiyor. Insert ifadelerine kimlik sütunları eklemeyin, toplu ekleme ifadeleri arasında tablolarınızınIDENTITY_INSERT
durumunu el ile ayarlayın veya insert ifadesiyle bir kimlik sütunu için açık değeri el ile belirtin. Daha fazla bilgi için bkz. SET IDENTITY_INSERT. - Toplu Kopyalama API'sinin sınırlamaları nedeniyle,
MONEY
,SMALLMONEY
,DATE
,DATETIME
,DATETIMEOFFSET
,SMALLDATETIME
,TIME
,GEOMETRY
veGEOGRAPHY
veri türleri şu anda bu özellik için desteklenmemektedir.
SQL Server örneğiyle ilgisiz hatalar nedeniyle sorgu başarısız olursa, sürücü hata iletisini günlüğe kaydeder ve toplu ekleme için özgün mantığa geri döner.
Örnek
Bu örnekte, hem normal hem de Toplu Kopyalama API'sinin senaryoları için bin satırlık toplu ekleme işlemi için kullanım örneği gösterilmektedir.
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.");
}
}
Sonuç:
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.
Ayrıca bkz.
JDBC sürücü ile performansı ve güvenilirliği artırma