Oracle JDBC中的語句緩存

發表于:2013-10-10來源:IT博客大學習作者:老熊點擊數: 標簽:oracle
在Oracle數據庫中,SQL解析有幾種: 硬解析,過多的硬解析在系統中產生shared pool latch和library cache liatch爭用,消耗過多的shared pool,使得系統不具有可伸縮性。

  在Oracle數據庫中,SQL解析有幾種:

  硬解析,過多的硬解析在系統中產生shared pool latch和library cache liatch爭用,消耗過多的shared pool,使得系統不具有可伸縮性。

  軟解析,過多的軟解析仍然可能會導致系統問題,特別是如果有少量的SQL高并發地進行軟解析,會產生library cache latch或者是share方式的mutex爭用。

  軟軟解析,其實這也也屬于軟解析,與普通的軟解析不同的是,軟軟解析的SQL會在會話的cached cursor中命中。

  一次解析,多次執行,這是解析次數最少的方式,也是系統最具有可擴展性的方式。

  那么在JAVA開發的應用中,怎么樣才能實現上述第4種方式?如果是循環處理某種數據,這個比較容易實現。其實對于不是這種情況,Oracle也提供了很好的方式來實現這一點。下面是一個例子(例子代碼文件為TestStmtCache.java)。

  import java.sql.*;

  import oracle.jdbc.driver.OracleConnection;

  public class TestStmtCache {

  public static Connection getConnection() throws Exception {

  String driver = "oracle.jdbc.driver.OracleDriver";

  String url = "jdbc:oracle:thin:@localhost:1521:xj11g";

  Class.forName(driver);

  return DriverManager.getConnection(url, "test", "test");

  }

  public static void main(String args[]) {

  Connection conn = null;

  try {

  conn = getConnection();

  conn.setAutoCommit(false);

  ((OracleConnection)conn).setStatementCacheSize(0);

  for (int i=0; i <200; i++) {

  testNoCache(conn);

  }

  ((OracleConnection)conn).setStatementCacheSize(20);

  ((OracleConnection)conn).setImplicitCachingEnabled(true);

  for (int i=0; i <200; i++) {

  testCache(conn);

  }

  } catch (Exception e) {

  e.printStackTrace();

  } finally {

  try {

  conn.close();

  } catch (SQLException e) {

  e.printStackTrace();

  }

  }

  }

  public static void testCache(Connection conn) {

  PreparedStatement pstmt = null;

  try {

  pstmt = conn.prepareStatement("select /*cache_test1 */ * from t1 where rownum<=1");

  pstmt.execute();

  } catch (Exception e) {

  e.printStackTrace();

  } finally {

  try {

  pstmt.close();

  } catch (SQLException e) {

  e.printStackTrace();

  }

  }

  }

  public static void testNoCache(Connection conn) {

  PreparedStatement pstmt = null;

  try {

  pstmt = conn.prepareStatement("select /*nocache_test1 */ * from t1 where rownum<=1");

  pstmt.execute();

  } catch (Exception e) {

  e.printStackTrace();

  } finally {

  try {

  pstmt.close();

  } catch (SQLException e) {

  e.printStackTrace();

  }

  }

  }

  }

  編譯上述代碼文件TestStmtCache.java,并運行:

  E:\JavaCode>set CLASSPATH=.;ojdbc14.jar

  E:\JavaCode>d:\works\Java\jdk1.5.0_21\bin\javac TestStmtCache.java

  E:\JavaCode>d:\works\Java\jdk1.5.0_21\jre\bin\java TestStmtCache

  在數據庫中進行查詢:

  SYS@xj11g> select sql_id,parse_calls,executions,sql_text from v$sqlarea where sql_text like '%cache_test%' and sql_text not like '%v$%';

  SQL_ID PARSE_CALLS EXECUTIONS SQL_TEXT

  ------------- ----------- ----------- ------------------------------------------------------------

  3nbu9qp40ptjk 200 200 select /*nocache_test1 */ * from t1 where rownum< =1

  47hja0fwmmb6c 1 200 select /*cache_test1 */ * from t1 where rownum<=1

  可以看到,這兩條SQL語句,都執行了200次,但是標記為”nocache_test1″的SQL沒有進行語句緩存,其parse calls為200次,即解析了200次,其中一次是硬解析。而標記為”cache_test1″的SQL語句,使用了語句緩存,但是parse calls只有1次,即只有一次硬解析,執行了200次。這里關鍵的代碼在于:

  ((OracleConnection)conn).setStatementCacheSize(20);

  ((OracleConnection)conn).setImplicitCachingEnabled(true);

  上述第一行代碼設置語句緩存大小,當然20比較偏小,對于比較大型的系統來說,設到200-300比較合適,不過這會耗用一定數量的JAVA內存。這個數值表示一個連接能夠緩存多少語句。第二行代碼是設置隱式打開語句緩存,也即自動會對PreparedStatement的SQL語句進行緩存。

  那么,上述的方式無疑是比較簡單的,但是這種方式有一個問題就是,緩存的利用效率可能不高,因為JAVA會將不常用的SQL語句也進行了緩存。Oracle的JDBC驅動也提供了一種手工控制的方式:

  將測試代碼中的第22行替換為:

  ((OracleConnection)conn).setExplicitCachingEnabled(true);

原文轉自:http://blogread.cn/it/article/6685

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97