1.使用Statement對象 2.預(yù)編譯PreparedStatement 3.使用PreparedStatement + 批處理 為了區(qū)分出這三者之間的效率,,下面的事例執(zhí)行過程都是在數(shù)據(jù)庫表t1中插入1萬條記錄,,并記錄出所需的時間(此時間與電腦硬件有關(guān)) 1.使用Statement對象 使用范圍:當(dāng)執(zhí)行相似SQL(結(jié)構(gòu)相同,,具體值不同)語句的次數(shù)比較少 優(yōu)點:語法簡單 缺點:采用硬編碼效率低,,安全性較差,。 原理:硬編碼,,每次執(zhí)行時相似SQL都會進(jìn)行編譯
事例執(zhí)行過程: public void exec(Connection conn){ try { Long beginTime = System.currentTimeMillis(); conn.setAutoCommit(false);//設(shè)置手動提交 Statement st = conn.createStatement(); for(int i=0;i<10000;i++){ String sql="insert into t1(id) values ("+i+")"; st.executeUpdate(sql); } Long endTime = System.currentTimeMillis(); System.out.println("Statement用時:"+(endTime-beginTime)/1000+"秒");//計算時間 st.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } }
執(zhí)行時間:Statement用時:31秒
2.預(yù)編譯PreparedStatement 使用范圍:當(dāng)執(zhí)行相似sql語句的次數(shù)比較多(例如用戶登陸,對表頻繁操作..)語句一樣,,只是具體的值不一樣,,被稱為動態(tài)SQL 優(yōu)點:語句只編譯一次,減少編譯次數(shù),。提高了安全性(阻止了SQL注入) 缺點: 執(zhí)行非相似SQL語句時,,速度較慢。 原理:相似SQL只編譯一次,,減少編譯次數(shù) 名詞解釋: SQL注入:select * from user where username="張三" and password="123" or 1=1; 前面這條語句紅色部分就是利用sql注入,,使得這條詞句使終都會返回一條記錄,從而降低了安全性,。 事例執(zhí)行過程: public void exec2(Connection conn){ try { Long beginTime = System.currentTimeMillis(); conn.setAutoCommit(false);//手動提交 PreparedStatement pst = conn.prepareStatement("insert into t1(id) values (?)"); for(int i=0;i<10000;i++){ pst.setInt(1, i); pst.execute(); } conn.commit(); Long endTime = System.currentTimeMillis(); System.out.println("Pst用時:"+(endTime-beginTime)+"秒");//計算時間 pst.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } 執(zhí)行時間:Pst用時:14秒
3.使用PreparedStatement + 批處理 使用范圍:一次需要更新數(shù)據(jù)庫表多條記錄 優(yōu)點:減少和SQL引擎交互的次數(shù),,再次提高效率,相似語句只編譯一次,減少編譯次數(shù),。提高了安全性(阻止了SQL注入) 缺點: 原理: 批處理: 減少和SQL引擎交互的次數(shù),,一次傳遞給SQL引擎多條SQL。 名詞解釋: PL/SQL引擎:在oracle中執(zhí)行pl/sql代碼的引擎,,在執(zhí)行中發(fā)現(xiàn)標(biāo)準(zhǔn)的sql會交給sql引擎進(jìn)行處理,。 SQL引擎:執(zhí)行標(biāo)準(zhǔn)sql的引擎。 事例執(zhí)行過程: public void exec3(Connection conn){ try { conn.setAutoCommit(false); Long beginTime = System.currentTimeMillis(); PreparedStatement pst = conn.prepareStatement("insert into t1(id) values (?)");
for(int i=1;i<=10000;i++){ pst.setInt(1, i); pst.addBatch();//加入批處理,,進(jìn)行打包 if(i%1000==0){//可以設(shè)置不同的大小,;如50,100,,500,,1000等等 pst.executeBatch(); conn.commit(); pst.clearBatch(); } } pst.executeBatch(); Long endTime = System.currentTimeMillis(); System.out.println("pst+batch用時:"+(endTime-beginTime)+"毫秒"); pst.close(); conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 執(zhí)行時間:pst+batch用時:485毫秒 摘自:http://www./topic/368990 |
|
來自: 燮羽 > 《數(shù)據(jù)庫》