“綁定變量”這個詞也許對於某些人來說看以來陌生,其實我們在很早的時候就已經開始運用它了。
在java中使用的PrepareStatement對象,大家一定會說這不是將sql語句做預編譯操作嘛,被封裝的sql語句可以包含動參數,減少編譯的次數,提高數據庫性能,減輕jvm的負荷。
其實“綁定變量”的用途就是如上邊所說。
那么我們用到它的前提是,大量批量操作,條件相同,但參數值不同。
網上有這樣的例子
CREATE TABLE TTT1 (X INT); CREATE OR REPLACE PROCEDURE PROC1 AS BEGIN FOR i IN 1 .. 100000 LOOP EXECUTE IMMEDIATE 'INSERT INTO TTT1 VALUES(:X)' USING i; END LOOP; END; / CREATE OR REPLACE PROCEDURE PROC2 AS BEGIN FOR i IN 1 .. 100000 LOOP EXECUTE IMMEDIATE 'INSERT INTO TTT1 VALUES('||i||')'; END LOOP; END; / 兩個存儲過程都很簡單,都是向表TTT1中插入1-100000條記錄,唯一的不同是proc1使用了綁定變量:x,proc2沒有使用綁定變量,我們來簡單的看一下執行時間: ETL@DWTEST> EXEC PROC1; PL/SQL procedure successfully completed. Elapsed: 00:00:02.80 ETL@DWTEST> EXEC PROC2; PL/SQL procedure successfully completed. Elapsed: 00:00:06.27 可以看到PROC2的執行時間幾乎是PROC1執行時間的3倍! TOM曾說過:Oracle 將已解析、已編譯的SQL 連同其他內容存儲在共享池(shared pool)中,這是系統全局區(System Global Area ,SGA)中一個非常重要的共享內存結構。如果你確實想讓Oracle 緩慢地運行,甚至幾近停頓,只要根本不使用綁定變量就可以辦到。 如果使用綁定變量,無論是誰,只要提交引用同一對象的同一個查詢,都會使用共享池中已編譯的查詢計划。這樣你的子例程只編譯一次就可以反復使用。這樣做效率很高,這也正是數據庫期望你采用的做法。你使用的資源會更少(軟解析耗費的資源相當少),不僅如此,占用閂的時間也更短,而且不再那么頻繁地需要閂。這些都會改善應用的性能和可擴縮性。 實際上,proc2 需要的時間幾乎是proc1 的3 倍,這說明,在這種情況下,對於每個“無綁定變量”的INSERT,執行語句所需時間中有2/3 僅用於解析語句!因此,請檢查一下我們曾經寫過的程序,看一看是否可以使用綁定變量,如果真的可以使用綁定變量,那我確信程序經過修改可以提高一大截性能!
JAVA中綁定變量的測試代碼 2012-04-12 11:54 達內培訓 寫這篇文章的目的並不想為你講述什么樣的知識,只是希望為你提供幫助。大家可以將代碼測試一下,理解其實現原理,對大家學習肯定能有所幫助 一段在JAVA中綁定變量的測試代碼,達內培訓為你整理。 import java.sql.*; import oracle.jdbc.driver.*; class ConOra { public static void main(String args[] ) throws SQLException{ DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.152:1521:whx","system","lukewhx"); PreparedStatement stmt ; ResultSet rset ; String v_sql; /* for (int i =1;i<=1000;i++){ v_sql="select object_name from objects where object_id="+i; stmt =conn.prepareStatement(v_sql); rset=stmt.executeQuery(); stmt.close(); } */ for (int i =1 ;i<=1000;i++ ) { v_sql = "select object_name from objects where object_id= :x "; stmt=conn.prepareStatement(v_sql); stmt.setString(1,Integer.toString(i)); rset = stmt.executeQuery(); stmt.close(); } System.out.println("Execute OK"); } }