1. ??
JDBC??? ?? ?? dml ?? ????? ??? ? ?? ???? ???, ????? ???? ??? ???? ?? ????. mysql? oracle?? ?? ??? ???? ??? ?????? ? ????? ?? ?? ??? ?????.
2. ?? ??
? ??? ?? ? ??? ?? ?????
a. mysql?? jdbc? ?? ??? ???? ??? ?????
b. ??? oracle
c?? jdbc? ?? ??? ?????. oracle plsql ?? ?? ? ?? ??? ???? ??? ?????.
?? Java ? ?????? ??? ??? ????: Java17, Mysql8, Oracle11G
3. ?? mysql? oracle? ???
create table t ( -- mysql中創(chuàng)建表的語句 id int, name1 varchar(100), name2 varchar(100), name3 varchar(100), name4 varchar(100) );
create table t ( -- oracle中創(chuàng)建表的語句 id number, name1 varchar2(100), name2 varchar2(100), name3 varchar2(100), name4 varchar2(100) );
?? ?? ?????? ??? ???? ???.
mysql? ??? ?????.
set global general_log = 1;
oracle? ??? ?????.
alter system set audit_trail=db, extended; audit insert table by scott; -- 實驗采用scott用戶批量執(zhí)行insert的方式
java ??? ??? ????.
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); } }
???? ??? ? ?? ???
- mysql url? useServerPrepStmts= true&rewriteBatchedStatements=true ????? ???? ???.
- batchCnt? ? ???? ??? SQL ? ?? ????, 0? ?? ??? ?????.
- ? ?? mysql ???
exec("mysql", 10000, batchCnt);
?? ??? ????? ?? ??Cnt ?? ?????
batchCnt=50 ? ?? ?: 10000, ??? ??: 50, ? ?? ??: 4369???batchCnt= 100 ? ?? ?: 10000, ? ?? ??: 100, ? ?? ??: 2598???batchCnt=200 ? ?? ?: 10000, ? ?? ??: 200, ? ?? ??: 2211???
?? ?? ??
batchCnt=1000 ?? ?? ?: 10000, ? ?? ??: 1000, ? ?? ??: 2099???
batchCnt=10000 ? ?? ?: 10000, ? ?? ??: 10000, ? ?? ??: 2418???
batchCnt=0 ? ?? ? : 10000, ?? ??, ? ?? ??: 59620???
batchCnt=5
batchCnt=0
? ?? ??? ?? ? ????.
- ?? ??? ???? ??? ?? ?? ???????. ?? ????.
- mysql? ?? ??? ??? SQL? ?? ???? ?? ??? ?? xx ?(),()...? ???? ?????.
- batchCnt? 50?? 100?? ???? ????? ??? ???? ????? ?? ???? ?? ??? ???? ?? ?? ??? ?????.
- ?? ??:
? ?? ?, 1? ?? ??? ???? ??? ???? ? ?? 1? ?? ??? ?? ??? ? ???? ?? ????. ?? ??? ?? ??? ???? ????. ?? ????? 1? ?? SQL ?? ????? ?? ? ?? ??? ?? ? ???? ????. ? ??? mysql?? ??? ???? max_allowed_packet? ????. ?? ?? ??? ?? 1GB???. ?? ?? ?? "??? ??? ?? ???(1,773,901 > 1,599,488). 'max_allowed_packet' ??? ???? ???? ? ?? ??? ? ????."?? ???? ?????.
???? oracle? ???
exec("oracle", 10000, batchCnt);
?? ??? ????? ?? ??Cnt ?? ?????
batchCnt=50 ? ?? ?: 10000, ? ?? ??: 50, ? ?? ??: 2055???batchCnt=100 ? ?? ?: 10000, ? ?? ??: 100, ? ?? ??: 1324???batchCnt=200 ? ?? ?: 10000, ? ?? ??: 200, ? ?? ??: 856???
Oracle?? ?? ??? ????? MySQL? ???? ?? ??? ???? ?? ???? ?? ????. ??? Oracle? xx ? ??(),()... ??? ??? ????. ??? ?? ??? ??? ??????
batchCnt=1000 ? ?? ?? ?: 10000, ? ?? ??: 1000, ? ?? ??: 785???
batchCnt=10000 ? ?? ?: 10000, ? ?? ??: 10000, ? ?? ??: 804???
batchCnt=0 ? ?? ?: 10000, ?? ??, ? ?? ??: 60830???
batchCnt=50? ??? ? ?? ? dba_audit_trail ??
從審計的結(jié)果中可以看到,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方法在記錄內(nèi)容方面相同。因此可以推斷,JDBC的executeBatch和存儲過程的批量執(zhí)行都采用了相同的方法
存儲過程的這個關(guān)鍵點就是forall。查閱相關(guān)文檔。
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ù)。
? ??? Java?? JDBC ?? ??? ???? ??? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? AI ??

Undress AI Tool
??? ???? ??

Undresser.AI Undress
???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover
???? ?? ???? ??? AI ?????.

Clothoff.io
AI ? ???

Video Face Swap
??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

?? ??

??? ??

???++7.3.1
???? ?? ?? ?? ???

SublimeText3 ??? ??
??? ??, ???? ?? ????.

???? 13.0.1 ???
??? PHP ?? ?? ??

???? CS6
??? ? ?? ??

SublimeText3 Mac ??
? ??? ?? ?? ?????(SublimeText3)

??? ??











OnedeDeDcolumnsimprovesperformanceByresourceUsage.1. FetchingAllColumnsIncreasesMemory, Network ? ProcessingOverHead.2.UneCessaryDatareTrevalPreventSeffectiveIndEvuse, RaisesDiski/O ? SloweryExcution.3.toptimize, Edrooptimize, Edrooptimize

Java? ??? ?? ? ?? ?? ?? ???? ?? ??????. 1. ?? ??? ??? ??????. 2. ? ?? ?? ?? ??? ?? ?? ?? ???????. 3. ? ??? ??? ???? ??, ??? ? ??? ?? ? ? ????. 4. ??? ?? ??? ? ??, ?? ??? ????, name (), ordinal (), value () ? valueof ()? ?? ?? ???? ?????. 5. ??? ??? ?? ??, ??? ? ???? ???? ? ??? ?? ??, ?? ?? ?? ?? ??? ?? ????? ?????.

HTML?? ??? ??? ????? ???? ??? ?? ???, ??? ? SEO ??? ?? ? ? ????. 1. ??? ????? ??? ?? ??? ? ??? ??? ????? ?? ????????. 2. ????? ??? ???? ?? ?? ???? ???? ???? ?? ??? ?????. 3. ? ???? ??? ?? ??? ????? ??? ? ?? ?? ?? ?? ????? ?? ??? ????. ?? ???? ??? ??????? ?? ??? ??? ??? ???? ???? ??? ??? ?? ??? ???? ???????.

JDK (Javadevelopmentkit)? Java ?? ???? ? ???? ?????? ????? ?? ?????. Java ????? ???, ??? ? ???? ? ??? ?? ? ?????? ???? ????. ?? ?? ???? Java Compiler (JAVAC), JRE (Java Runtime Environment), Java Interpreter (Java), Debugger (JDB), ?? ?? ?? (Javadoc) ? ?? ?? (? : JAR ? JMOD)? ?????. ???? JDK? Java ??? ???? ????? IDE? ???? ???????. JDK? ??? Java ?? ????? ????? ??? ? ????. ???? Javac-Version ? Java Version? ?? ? ? ????

VSCODE?? Java ??? ??? ???? ?? ???? ??? ?????. 1. JDK ?? ? ??; 2. Javaextensionpack ? Debuggerforjava ????? ??????. 3. launch.json ?? ?? ? ?? MainClass ? ProjectName? ?????. 4. ?? ?? ??? ??? ??? ???? ???? ?? ??? ???? ??? ??????. 5. Watch, F8/F10/F11 ?? ?? ? ? ??? ?? ??? ??? ???? ???? ?? ???? JVM ?? ?? ??? ?? ???? ??? ??????.

Java ??? VSCODE? ????? ??? ???? ???? JDK? ???? ?? ??? ???????. 1. ?? ??, ??? ??, ?? ?? ? ?? ?? ??? ??? Javaextensionpack? ?????. ?? Javatestrunner ?? SpringBoot Extension ???. 2. ??? JDK17? ???? Java-Version ? Javac-Version? ?? ??????. Java_Home ?? ??? ????? VSCODE ??? ?? ?? ??? ?? JDK? ??????. 3. ???? ??? ?? ???? ??? ???? ?? ??? ?????, ?? ??? ????, ?? ??? ?????, ??? ??? ???? ???? ???????.

Windows ?? ??? ???? ?? ? ??? ?? ?? ???? ??? ????. 1. Explorer ?? ???? ?? ???? ?? ???? ?? "Windows Explorer"????? ?? ????? ??? ?? ?? ??????. 2. ?? ??? ??? ?? ????, ?? ?? ?? ?? Microsoft? ?? ??? ???? ?? ?? ??? ??? ??????. 3. ??? ?? ?? ??? ???? ??? ??? ???? ?? ?? ?????? SFC/Scannow ??? ?????. 4. ?? ???? ?????? ? ???? "???"? "?? ??"? ?? ? ??????. ????? ??? ?? ??? ??? ???? ???? ??? ???? ??? ? ????.

?? ???? theserializableinterfaceinjavaallowsaclasstobectobectedintoabytestreamforstorageortransmission. asamarkerfacewithnomethods, itsignals theclassissiadeforserialization, inablingmekerisms likeobjectoutoutputstreamtoprocessit.failingtoimple
