Menggunakan API salin massal untuk operasi penyisipan batch
Microsoft JDBC Driver untuk SQL Server versi 9.2 ke atas mendukung penggunaan API Salin Massal untuk operasi penyisipan batch. Fitur ini memungkinkan pengguna untuk mengaktifkan driver untuk melakukan operasi Salin Massal di bawahnya saat menjalankan operasi penyisipan batch. Driver bertujuan untuk mencapai peningkatan performa sambil menyisipkan data yang sama dengan yang akan dimiliki driver dengan operasi penyisipan batch reguler. Driver mengurai Kueri SQL pengguna, menggunakan API Salin Massal alih-alih operasi penyisipan batch biasa. Pengaturan berikut adalah berbagai cara untuk mengaktifkan API Salin Massal untuk fitur sisipan batch dan mencantumkan batasannya. Halaman ini juga berisi kode sampel kecil yang menunjukkan penggunaan dan peningkatan performa juga.
Fitur ini hanya berlaku untuk Api & executeLargeBatch()
PreparedStatement dan CallableStatement executeBatch()
.
Prasyarat
Prasyarat untuk mengaktifkan Bulk Copy API untuk penyisipan batch.
- Kueri harus berupa kueri sisipkan (kueri mungkin berisi komentar, tetapi kueri harus dimulai dengan kata kunci INSERT agar fitur ini mulai berlaku).
Mengaktifkan API salinan massal untuk penyisipan batch
Ada tiga cara untuk mengaktifkan Bulk Copy API untuk penyisipan batch.
1. Mengaktifkan dengan properti koneksi
useBulkCopyForBatchInsert=true;
Menambahkan ke string koneksi mengaktifkan fitur ini.
Connection connection = DriverManager.getConnection("jdbc:sqlserver://<server>:<port>;userName=<user>;password=<password>;database=<database>;encrypt=true;useBulkCopyForBatchInsert=true;");
2. Mengaktifkan dengan metode setUseBulkCopyForBatchInsert() dari objek SQLServerConnection
Memanggil SQLServerConnection.setUseBulkCopyForBatchInsert(true) memungkinkan fitur ini.
SQLServerConnection.getUseBulkCopyForBatchInsert() mengambil nilai saat ini untuk properti koneksi useBulkCopyForBatchInsert .
Nilai untuk useBulkCopyForBatchInsert tetap konstan untuk setiap PreparedStatement pada saat inisialisasinya. Panggilan berikutnya ke SQLServerConnection.setUseBulkCopyForBatchInsert() tidak memengaruhi nilai PreparedStatement yang sudah dibuat.
3. Mengaktifkan dengan metode setUseBulkCopyForBatchInsert() dari objek SQLServerDataSource
Mirip dengan opsi sebelumnya, tetapi menggunakan SQLServerDataSource untuk membuat objek SQLServerConnection. Kedua metode mencapai hasil yang sama.
Pembatasan yang diketahui
Saat ini ada batasan yang berlaku untuk fitur ini.
- Sisipkan kueri yang berisi nilai non-parameter (misalnya,
INSERT INTO TABLE VALUES (?, 2
)), tidak didukung. Kartubebas (?) adalah satu-satunya parameter yang didukung untuk fungsi ini. - Sisipkan kueri yang berisi ekspresi INSERT-SELECT (misalnya,
INSERT INTO TABLE SELECT * FROM TABLE2
), tidak didukung. - Sisipkan kueri yang berisi beberapa ekspresi VALUE (misalnya,
INSERT INTO TABLE VALUES (1, 2) (3, 4)
), tidak didukung. - Sisipkan kueri yang diikuti oleh klausa OPTION, digabungkan dengan beberapa tabel, atau diikuti oleh kueri lain, tidak didukung.
IDENTIY_INSERT
tidak dikelola di driver. Jangan sertakan kolom identitas dalam pernyataan penyisipan, aturIDENTITY_INSERT
status tabel Anda secara manual antara pernyataan sisipan batch, atau teruskan nilai eksplisit secara manual untuk kolom identitas dengan pernyataan sisipkan. Untuk informasi selengkapnya, lihat MENGATUR IDENTITY_INSERT.- Karena keterbatasan Bulk Copy API,
MONEY
, ,SMALLMONEY
,DATE
,DATETIME
,DATETIMEOFFSET
,SMALLDATETIME
,TIME
,GEOMETRY
danGEOGRAPHY
jenis data, saat ini tidak didukung untuk fitur ini.
Jika kueri gagal karena kesalahan yang tidak terkait dengan instans SQL Server, driver mencatat pesan kesalahan dan kembali ke logika asli untuk sisipan batch.
Contoh
Contoh ini menunjukkan kasus penggunaan untuk operasi penyisipan batch dari seribu baris, untuk skenario API Salin reguler vs Massal.
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.");
}
}
Hasil:
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.