1 Penerangan
Dalam JDBC, kaedah executeBatch boleh melaksanakan berbilang penyataan dml dalam kelompok, yang jauh lebih cekap daripada melaksanakan executeUpdate secara individu Apakah prinsipnya? Bagaimana untuk melaksanakan pelaksanaan batch dalam mysql dan oracle? Artikel ini akan memperkenalkan kepada anda prinsip di sebalik ini.
2. Pengenalan eksperimen
Eksperimen ini akan dijalankan melalui tiga langkah berikut
a
b. Catatkan masa yang memakan masa untuk pelaksanaan batch dan satu pelaksanaan jdbc dalam Oracle
c. versi java dan pangkalan data yang berkaitan adalah seperti berikut: Java17, Mysql8, Oracle11G
3 Percubaan formal
Buat jadual dalam mysql dan oracle masing-masing
create table t ( -- mysql中創(chuàng)建表的語句 id int, name1 varchar(100), name2 varchar(100), name3 varchar(100), name4 varchar(100) );rrree
Anda perlu menghidupkan audit pangkalan data sebelum percubaan
MySQL mula mengaudit:
create table t ( -- oracle中創(chuàng)建表的語句 id number, name1 varchar2(100), name2 varchar2(100), name3 varchar2(100), name4 varchar2(100) );
Oracle mula mengaudit:
set global general_log = 1;
kod java adalah seperti berikut:
alter system set audit_trail=db, extended; audit insert table by scott; -- 實驗采用scott用戶批量執(zhí)行insert的方式
A beberapa perkara yang perlu diperhatikan dalam kod,
- URL mysql perlu menambah useServerPrepStmts=true&rewriteBatchedStatements=parameter benar.
- batchCnt mewakili bilangan pernyataan SQL yang dilaksanakan dalam setiap kelompok, dan 0 mewakili pelaksanaan tunggal.
- Ujian pertama mysql
import java.sql.*; public class JdbcBatchTest { /** * @param dbType 數(shù)據(jù)庫類型,oracle或mysql * @param totalCnt 插入的總行數(shù) * @param batchCnt 每批次插入的行數(shù),0表示單條插入 */ public static void exec(String dbType, int totalCnt, int batchCnt) throws SQLException, ClassNotFoundException { String user = "scott"; String password = "xxxx"; String driver; String url; if (dbType.equals("mysql")) { driver = "com.mysql.cj.jdbc.Driver"; url = "jdbc:mysql://ip/hello?useServerPrepStmts=true&rewriteBatchedStatements=true"; } else { driver = "oracle.jdbc.OracleDriver"; url = "jdbc:oracle:thin:@ip:orcl"; } long l1 = System.currentTimeMillis(); Class.forName(driver); Connection connection = DriverManager.getConnection(url, user, password); connection.setAutoCommit(false); String sql = "insert into t values (?, ?, ?, ?, ?)"; PreparedStatement preparedStatement = connection.prepareStatement(sql); for (int i = 1; i <= totalCnt; i++) { preparedStatement.setInt(1, i); preparedStatement.setString(2, "red" + i); preparedStatement.setString(3, "yel" + i); preparedStatement.setString(4, "bal" + i); preparedStatement.setString(5, "pin" + i); if (batchCnt > 0) { // 批量執(zhí)行 preparedStatement.addBatch(); if (i % batchCnt == 0) { preparedStatement.executeBatch(); } else if (i == totalCnt) { preparedStatement.executeBatch(); } } else { // 單條執(zhí)行 preparedStatement.executeUpdate(); } } connection.commit(); connection.close(); long l2 = System.currentTimeMillis(); System.out.println("總條數(shù):" + totalCnt + (batchCnt>0? (",每批插入:"+batchCnt) : ",單條插入") + ",一共耗時:"+ (l2-l1) + " 毫秒"); } public static void main(String[] args) throws SQLException, ClassNotFoundException { exec("mysql", 10000, 50); } }
Masukkan nilai batchCnt ??yang berbeza untuk melihat masa pelaksanaan
batchCnt=50 Jumlah bilangan item : 10000, setiap kelompok Sisipan: 50, jumlah masa yang dibelanjakan: 4369 milisaatbatchCnt=100 Jumlah bilangan entri: 10000, sisipan dalam setiap kelompok: 100, jumlah masa yang dibelanjakan: 2598 milisaat? Lihat log umumbatchCnt=5batchCnt=0Kita boleh membuat beberapa kesimpulan:Jumlah bilangan kumpulan=2 penyertaan: 10000, sisipan dalam setiap kelompok: 200, jumlah masa yang dibelanjakan: 2211 milisaat
batchCnt=1000 Jumlah bilangan penyertaan: 10000, setiap kumpulan sisipan: 1000, jumlah masa yang dibelanjakan: 2099 milisaat
0 batch ? bilangan penyertaan: 10000, setiap kumpulan sisipan: 10000, Jumlah masa yang dibelanjakan: 2418 milisaat
batchCnt=0 Jumlah bilangan penyertaan: 10000, sisipan tunggal, jumlah masa yang dibelanjakan: 59620 milisaat
- Kecekapan pelaksanaan kelompok bertambah baik berbanding dengan pelaksanaan tunggal.
- Pelaksanaan kelompok mysql sebenarnya menulis semula sql dan menggabungkan berbilang sisipan ke dalam sisipan nilai xx(),()... untuk pelaksanaan.
- Apabila menukar batchCnt daripada 50 kepada 100, masa pada dasarnya dipendekkan separuh, tetapi apabila nilainya diperluaskan, pengurangan masa tidak jelas, dan masa pelaksanaan akan meningkat. tinggi.
Selepas klien menghantar pernyataan SQL untuk dilaksanakan ke pelayan pangkalan data, pangkalan data melaksanakan pernyataan SQL dan mengembalikan hasilnya kepada pelanggan. Jumlah masa yang diambil = masa pelaksanaan pangkalan data + masa penghantaran rangkaian. Mengurangkan bilangan perjalanan pergi dan balik melalui pelaksanaan kelompok mengurangkan masa pemindahan rangkaian dan oleh itu masa keseluruhan. Walau bagaimanapun, apabila batchCnt menjadi lebih besar, walaupun masa penghantaran rangkaian tidak lagi menjadi halangan utama, pengurangan dalam jumlah masa tidak akan begitu jelas. Terutama apabila batchCnt=10000, iaitu, semua 10,000 pernyataan dilaksanakan pada satu masa, masa menjadi lebih lama Ini mungkin kerana program dan pangkalan data perlu memohon memori yang lebih besar apabila menyediakan parameter input ini, jadi ia memerlukan lebih banyak masa. Saya rasa).
Lagi satu, boleh tak nilai batchCnt tak terhingga? Sudah tentu tidak, kami tidak menganggap masalah ruang untuk membatalkan Pertama sekali, komputer anda tidak mempunyai memori yang besar untuk menyimpan semua 100 juta parameter input SQL sekaligus Kedua, mysql juga mempunyai parameter max_allowed_packet untuk dihadkan panjang satu pernyataan Maksimum ialah 1Gbyte. Apabila pernyataan terlalu panjang, "Paket untuk pertanyaan terlalu besar (1,773,901 > 1,599,488). Anda boleh menukar nilai ini pada pelayan dengan menetapkan pembolehubah 'max_allowed_packet'" akan dilaporkan. Uji oracle seterusnyaexec("mysql", 10000, batchCnt);Masukkan nilai batchCnt ??yang berbeza untuk melihat masa pelaksanaan
Kesan pelaksanaan dalam Oracle ialah pada asasnya sama seperti dalam MySQL, dan kecekapan operasi pemprosesan kelompok jelas tinggi Dilaksanakan dalam satu baris. Masalahnya ialah tiada nilai sisipan xx(),()... sintaks dalam Oracle, jadi bagaimanakah ia mencapai pelaksanaan kelompok? Lihat paparan audit dba_audit_trail?> apabila batchCnt=50 dilaksanakanbatchCnt=0 Jumlah bilangan entri: 10000, sisipan tunggal, jumlah penggunaan masa: 60830 milisaat
batchCnt=50 Jumlah bilangan penyertaan: 10000, setiap kumpulan sisipan: 50, jumlah penggunaan masa: 2055 milisaat
batchCnt=100 Jumlah bilangan penyertaan: 10000, setiap sisipan kelompok: 100, jumlah penggunaan masa: 1324 milisaat
batchCnt=200 Jumlah bilangan penyertaan: 10 kumpulan000 sisipan: 200, jumlah penggunaan masa : 856 milisaat
batchCnt=1000 Jumlah bilangan entri: 10000, setiap kumpulan sisipan: 1000, jumlah masa yang dibelanjakan: 785 milisaat
batchCnt=10000: Jumlah setiap 1000 entri kumpulan sisipan: 10000, jumlah masa yang dibelanjakan: 804 Milisaat
從審計的結果中可以看到,batchCnt=50的時候,審計記錄只有200條(扣除登入和登出),也就是sql只執(zhí)行了200次。sql_text沒有發(fā)生改寫,仍然是"insert into t values (:1 , :2 , :3 , :4 , :5 )",而且sql_bind只記錄了批量執(zhí)行的最后一個參數(shù),即50的倍數(shù)。根據(jù)awr報告可以看出,實際只執(zhí)行了200次(由于篇幅限制,省略了awr截圖)。那么oracle是怎么做到只執(zhí)行200次但插入1萬條記錄的呢?我們來看看oracle中使用存儲過程的批量插入。
四、存儲過程
準備數(shù)據(jù):
首先將t表清空 truncate table t;
用java往t表灌10萬數(shù)據(jù) exec("oracle", 100000, 1000);
創(chuàng)建t1表 create table t1 as select * from t where 1 = 0;
以下兩個過程的意圖一致,均為將t表中的數(shù)據(jù)導入t1表。nobatch是單次執(zhí)行,usebatch是批量執(zhí)行。
create or replace procedure nobatch is begin for x in (select * from t) loop insert into t1 (id, name1, name2, name3, name4) values (x.id, x.name1, x.name2, x.name3, x.name4); end loop; commit; end nobatch; /
create or replace procedure usebatch (p_array_size in pls_integer) is type array is table of t%rowtype; l_data array; cursor c is select * from t; begin open c; loop fetch c bulk collect into l_data limit p_array_size; forall i in 1..l_data.count insert into t1 values l_data(i); exit when c%notfound; end loop; commit; close c; end usebatch; /
執(zhí)行上述存儲過程
SQL> exec nobatch; ?
Elapsed: 00:00:32.92
SQL> exec usebatch(50);
Elapsed: 00:00:00.77
SQL> exec usebatch(100);
Elapsed: 00:00:00.47
SQL> exec usebatch(1000);
Elapsed: 00:00:00.19
SQL> exec usebatch(100000);
Elapsed: 00:00:00.26
存儲過程批量執(zhí)行效率也遠遠高于單條執(zhí)行。查看usebatch(50)執(zhí)行時的審計日志,sql_bind也只記錄了批量執(zhí)行的最后一個參數(shù),即50的倍數(shù)。與使用executeBatch方法在記錄內容方面相同。因此可以推斷,JDBC的executeBatch和存儲過程的批量執(zhí)行都采用了相同的方法
存儲過程的這個關鍵點就是forall。查閱相關文檔。
The FORALL statement runs one DML statement multiple times, with different values in the VALUES and WHERE clauses.
The different values come from existing, populated collections or host arrays. The FORALL statement is usually much faster than an equivalent FOR LOOP statement.
The FORALL syntax allows us to bind the contents of a collection to a single DML statement, allowing the DML to be run for each row in the collection without requiring a context switch each time.
翻譯過來就是forall很快,原因就是不需要每次執(zhí)行的時候等待參數(shù)。
Atas ialah kandungan terperinci Bagaimana untuk melaksanakan sisipan kelompok JDBC di Jawa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Memilih.fetchingallcolumnsIncreaseMemory.2

Enums di Java adalah kelas khas yang mewakili bilangan tetap nilai tetap. 1. Gunakan definisi kata kunci enum; 2. Setiap nilai enum adalah contoh akhir statik awam jenis enum; 3. Ia boleh termasuk bidang, pembina dan kaedah untuk menambah tingkah laku kepada setiap pemalar; 4. Ia boleh digunakan dalam pernyataan suis, menyokong perbandingan langsung, dan menyediakan kaedah terbina dalam seperti nama (), ordinal (), nilai () dan nilai (); 5. Penghitungan boleh meningkatkan jenis keselamatan, kebolehbacaan dan fleksibiliti kod, dan sesuai untuk senario pengumpulan terhad seperti kod status, warna atau minggu.

Penggunaan rasional tag semantik dalam HTML dapat meningkatkan kejelasan struktur halaman, aksesibilitas dan kesan SEO. 1. Digunakan untuk blok kandungan bebas, seperti jawatan blog atau komen, ia mesti mandiri; 2. Digunakan untuk kandungan berkaitan klasifikasi, biasanya termasuk tajuk, dan sesuai untuk modul yang berlainan halaman; 3. Digunakan untuk maklumat tambahan yang berkaitan dengan kandungan utama tetapi tidak teras, seperti cadangan sidebar atau profil pengarang. Dalam perkembangan sebenar, label harus digabungkan dan lain -lain, elakkan bersarang yang berlebihan, pastikan struktur mudah, dan sahkan rasionalitas struktur melalui alat pemaju.

JDK (JavadevelopmentKit) adalah persekitaran pembangunan perisian untuk membangunkan aplikasi dan applet Java. Ia mengandungi alat dan perpustakaan yang diperlukan untuk menyusun, debug dan menjalankan program Java. Komponen terasnya termasuk Java Compiler (Javac), Java Runtime Environment (JRE), Java Interpreter (Java), Debugger (JDB), Alat Penjanaan Dokumen (Javadoc) dan alat pembungkusan (seperti JAR dan JMOD). Pemaju memerlukan JDK untuk menulis, menyusun kod Java dan membangunkan dengan bantuan IDE; Tanpa JDK, aplikasi Java tidak boleh dibina atau diubahsuai. Anda boleh memasukkan versi Javac dan Java-versi di terminal

Langkah -langkah utama dalam mengkonfigurasi persekitaran debugging Java pada vscode termasuk: 1. Pasang JDK dan Sahkan; 2. Pasang JavaextensionPack dan DebuggerForjava plug-in; 3. Buat dan konfigurasikan fail launch.json, tentukan Mainclass dan ProjectName; 4. Sediakan struktur projek yang betul untuk memastikan laluan kod sumber dan output penyusunan adalah betul; 5. Menggunakan teknik debugging seperti Watch, F8/F10/F11 kunci pintasan dan kaedah untuk menangani masalah biasa seperti kelas yang tidak dijumpai atau kegagalan lampiran JVM.

Untuk menggunakan vscode untuk pembangunan Java, anda perlu memasang sambungan yang diperlukan, konfigurasikan JDK dan sediakan ruang kerja. 1. Pasang JavaextensionPack, termasuk sokongan bahasa, penyepaduan debugging, membina alat dan fungsi penyelesaian kod; Pakej sambungan Javatestrunner atau Springboot pilihan. 2. Pasang sekurang-kurangnya JDK17 dan sahkan melalui versi Java dan Javac-version; Tetapkan pembolehubah persekitaran java_home, atau tukar jdks berbilang di bar status di bahagian bawah vscode. 3. Selepas membuka folder projek, pastikan struktur projek betul dan membolehkan penjimatan automatik, menyesuaikan peraturan pemformatan, membolehkan pemeriksaan kod, dan konfigurasikan tugas penyusunan untuk mengoptimumkan pembukaan.

Apabila bar carian Windows tidak dapat memasukkan teks, penyelesaian biasa adalah: 1. Mulakan semula penjelajah atau komputer, buka pengurus tugas untuk memulakan semula proses "Windows Explorer", atau mulakan semula peranti secara langsung; 2. Tukar atau nyahpasang kaedah input, cuba gunakan kaedah input bahasa Inggeris atau kaedah input Microsoft sendiri untuk menghapuskan konflik kaedah input pihak ketiga; 3. Jalankan alat semak fail sistem, laksanakan perintah SFC/ScanNow dalam arahan arahan untuk membaiki fail sistem; 4. Tetapkan semula atau membina semula indeks carian, dan membina semula melalui "pilihan indeks" dalam "panel kawalan". Biasanya, kita mulakan dengan langkah mudah terlebih dahulu, dan kebanyakan masalah dapat diselesaikan langkah demi langkah.

Pelaksanaan yang boleh dipertanggungjawabkan
