“綁定變量”這個詞也許對於某些人來說看以來陌生,其實我們在很早的時候就已經開始運用它了。
在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");
}
}
