Pertama, tiga metode pemrograman penyisipan batch JDBC diperkenalkan untuk membandingkannya. Konten spesifiknya adalah sebagai berikut
Penyisipan Batch JDBC terutama digunakan untuk impor data dan pencatatan karena log umumnya ditulis dalam file terlebih dahulu.
Saya menggunakan driver JDBC MySQL 5.1.5 untuk menguji tiga metode yang lebih umum digunakan
Metode 1: Gunakan persiapan disiapkan untuk menambahkan batch
coba {class.forname ("com.mysql.jdbc.driver"); conn = driverManager.getConnection (o_url, nama pengguna, kata sandi); Conn.setAutocommit (false); String sql = "masukkan adlog (ip, situs web, yyyymmdd, jam, objek_id) nilai (?,?,?,?,?)"; Persiapan Persiapan = Conn.PrepareStatement (SQL, hasilnya untuk (int x = 0; x <size; x ++) {prest.setstring (1, "192.168.1.1"); prest.setstring (2, "localhost"); prest.setstring (3, "20081009"); prest.setint (4, 8); prest.setstring (5, "11111111"); prest.addbatch (); } prest.executebatch (); Conn.Commit (); conn.close (); } catch (sqlexception ex) {logger.getLogger (myLogger.class.getName ()). Log (level.severe, null, ex); } catch (classNotFoundException ex) {logger.getLogger (myLogger.class.getName ()). Log (level.severe, null, ex); } Jelaskan arti dari dua parameter berikut saat membangun pernyataan:
Parameter pertama menentukan jenis hasil. Pilihannya adalah:
Type_forward_only: Jenis default. Akses ke depan hanya diizinkan sekali dan tidak akan terpengaruh oleh perubahan yang dibuat oleh pengguna lain ke database.
Type_scroll_insensitive: memungkinkan gerakan maju atau mundur dalam daftar, dan bahkan penentuan posisi tertentu, seperti pindah ke rekor keempat dalam daftar atau memindahkan dua catatan ke belakang dari posisi saat ini. Ini tidak akan terpengaruh oleh perubahan yang dibuat oleh pengguna lain ke database.
Type_scroll_sensitive: seperti type_scroll_insensitive, positioning diizinkan dalam catatan. Jenis ini dipengaruhi oleh perubahan yang dibuat oleh pengguna lain. Jika pengguna menghapus catatan setelah menjalankan kueri, catatan itu akan hilang dari hasil. Demikian pula, perubahan nilai data akan tercermin dalam hasil.
Parameter kedua menetapkan konkurensi hasil, yang menentukan apakah hasilnya dapat diperbarui. Pilihannya adalah:
Concur_read_only: ini adalah nilai default, ditentukan bahwa itu tidak dapat diperbarui
Hasil concur_updatable: menentukan bahwa hasilnya dapat diperbarui
Metode 2: Gunakan pernyataan untuk menambahkan metode batch
Conn.setAutocommit (false); Pernyataan stmt = conn.createStatement (resultet.type_scroll_sensitive, resultet.concur_read_only); untuk (int x = 0; x <size; x ++) {stmt.addbatch ("masukkan ke dalam adlog (ip, situs web, yyyymmdd, jam, objek_id) nilai ('192.168.1.3', 'localhost', '20081009', 8, '23123')"); } stmt.executebatch (); Conn.Commit ();Metode 3: Gunakan pernyataan secara langsung
Conn.setAutocommit (false); Pernyataan stmt = conn.createStatement (resultet.type_scroll_sensitive, resultet.concur_read_only); untuk (int x = 0; x <size; x ++) {stmt.execute ("masukkan ke dalam adlog (ip, situs web, yyyymmdd, jam, objek_id) nilai ('192.168.1.3', 'localhost', '20081009', 8, '23123')"); } conn.commit (); Waktu tes rata -rata untuk memasukkan 100.000 lembar data menggunakan metode di atas adalah:
Metode 1: 17.844s
Metode 2: 18.421S
Metode 3: 16.359S
Dapat dilihat bahwa penyisipan pernyataan batch JDBC tidak hanya tidak meningkatkan kinerja, tetapi lebih lambat daripada saat tidak ada batch yang digunakan. Tentu saja, ini mungkin terkait dengan metode implementasi driver spesifik JDBC. Lampirannya adalah kode uji saya, yang dapat digunakan untuk berjalan di komputer saya.
Saat melakukan penyisipan batch, yang paling penting adalah secara otomatis membatalkan pengiriman, jadi tidak masalah apakah sintaks batch JDBC digunakan atau tidak.
Conn.SetAutocommit (false)
Saya pribadi berpikir metode pertama adalah yang paling nyaman dan praktis.
Contoh Penjelasan Data Penyisipan Batch JDBC :
Baru -baru ini, ketika saya sedang mengerjakan program untuk mengimpor data Excel ke dalam database, saya sedang bersiap untuk menggunakan pemasangan batch JDBC karena sejumlah besar data. Jadi prepareStatement.addbatch () digunakan; Ketika 1W potongan data ditambahkan, operasi insert dilakukan, disiapkan statement.executebatch () digunakan. Saya pikir ini akan cepat, tetapi saya butuh lebih dari 30 menit untuk memasukkan 65.536 lembar data, yang benar -benar di luar harapan saya. Jadi saya bertanya kepada kolega saya bagaimana mereka memproses impor data skala besar semacam ini. Saya menemukan bahwa mereka juga menggunakan pemrosesan penyisipan batch JDBC, tetapi tidak seperti saya, mereka menggunakan con.setautocommit (false); kemudian disiapkan statement.executebatch () dan kemudian dieksekusi con.commit (); Jadi saya mencoba lagi, apa itu keajaiban? Hanya butuh setengah jam untuk mengimpor data ini, dan setelah menambahkan dua kalimat ini, hanya butuh 15 detik untuk menyelesaikannya. Jadi saya memeriksa alasannya dan menemukan penjelasan berikut secara online:
* Saat mengimpor data ke InnodB, pastikan bahwa MySQL tidak memiliki mode Autocommit diaktifkan karena itu
Membutuhkan flush log ke disk untuk setiap sisipan. Untuk menonaktifkan AutoCommit selama operasi impor Anda, mengelilinginya
Atur pernyataan autocommit dan komit:
Setel AutoCommit = 0;
... pernyataan impor SQL ...
MELAKUKAN;
Pertama kali, justru karena tidak ada komommit setautok (salah); Untuk setiap pernyataan insert, log akan dihasilkan ke disk. Oleh karena itu, meskipun insert batch diatur, efeknya seperti sisipan tunggal, menghasilkan penyisipan yang sangat lambat.
Beberapa kode adalah sebagai berikut:
String sql = "masukkan ke tabel *****"; con.setAutocommit (false); ps = con.preparestateMent (sql); for (int i = 1; i <65536; i ++) {ps.addbatch (); // Masukkan 1W Records sekali jika (i % 10000 == 0) {ps.executeBatch (); con.commit (); }} // Masukkan kurang dari 1W data ps.executebatch (); con.commit ();Di atas hanyalah lauk, dan kemudian "sajikan" diikuti oleh:
1. Data Penulisan Batch Uji
Long Start = System.CurrentTimeMillis (); Daorecord daorecord = new daorecord (); Daftar <T> Daftar = ArrayList baru <T> (); untuk (int i = 1; i <= 1000; i ++) {for (int j = 1; j <= 1000; j ++) {t t = new t (); t.seti (i); t.setj (j); list.add (t); }} daorecord.insertbatch (daftar); System.out.println ("Memakan waktu:" + (System.CurrentTimeMillis ()-Start) + "MS"); 2. Tes data penulisan batch
public void InsertBatch (Daftar <T> Daftar) {String SQL = "INSERT INTO T (GO, BACK) VALUES (?,?)"; Dbhelper dbh = dbhelper baru (sql); Koneksi conn = dbh.returnconn (); coba {conn.setAutocommit (false); // Perhatikan bahwa kalimat ini harus salah, lihat referensi pertama disiapkan ps = conn.preparestatement (sql); untuk (int i = 0; i <list.size (); i ++) {ps.setint (1, list.get (i) .geti ()); ps.setint (2, list.get (i) .getj ()); ps.addbatch (); if (i % 10000 == 0) {ps.executebatch (); Conn.Commit (); }} ps.executebatch (); Conn.Commit (); conn.close (); } catch (sqlexception e) {// TODO secara otomatis menghasilkan blok tangkapan e.printstacktrace (); }}Tabel Data:
Hasil Eksperimen:
Di atas adalah semua tentang artikel ini, saya harap ini akan membantu untuk pembelajaran semua orang.