oracle11g缓存和连接池-3
缓存与程序包变量
??? 对 SQL 结果缓存和 PL/SQL 函数缓存,您也可以使用程序包变量(可以是标量数据类型或 PL/SQL 集合)实现在内存中缓存值。应用程序可以访问变量,而不是表行或函数。因为基于内存,它的行为像缓存,那么 SQL 结果缓存添加了什么值?
??? 差别众多。对一个客户(假设 cust_id = 5)执行该函数后,从另一个 会话对同一客户执行该函数:
SQL> select get_tax_rate(&n) from dual
2 /
Enter value for n: 5
old?? 1: select get_tax_rate(&n) from dual
new?? 1: select get_tax_rate(5) from dual
GET_TAX_RATE(5)
---------------
????????????? 6
1 row selected.
Elapsed: 00:00:00.00
??? 注意执行时间,它表明结果源自缓存,而不是通过函数的执行。因此,尽管会话中没有缓存该函数,任一调用它的会话仍然可以从缓存中使用它。
??? 缓存针对数据库实例,而不是会话。这一让所有其他会话能使用一个会话中的缓存的能力极其不同于使用程序包变量在内存中保存值的方法,在这一方法中,变量只能在一个会话中可见。
??? 而且,程序包变量无法感知底层表的更改。当数据更改时,您需要手动刷新数据,否则应用程序将获取陈旧数据。在底层表数据更改时,SQL 结果缓存和 PL/SQL 函数缓存会自动刷新缓存,不需用户介入
?
Result-Cached Functions的一些限制
客户端查询结果缓存
??? 假设有这样一个情形:客户端需要通过慢速网络链接调用同一数据。尽管数据库可以立即将结果从缓存发送到客户端,但结果必须通过线路传送到客户端,这就增加了整体执行时间。现在有一些专门的中间件框架(如 Oracle Coherence),用于在??? try {
????? conn = DriverManager.getConnection( jdbcURL, "arup" , "arup");
????? System.out.println("Connected to Database");
??? } catch (SQLException sqlEx) {
????? System.out.println(" Error connecting to database : " + sqlEx.toString());
??? }
}
public void doSomething() throws SQLException?? {
??? Statement stmt = null;
??? ResultSet rset = null;
??? try {
????? stmt = conn.createStatement();
????? System.out.println("Created Statement object");
????? rset = stmt.executeQuery("select /*+ result_cache */ * from customers");
????? System.out.println("Retrieved ResultSet object");
????? if(rset.next())
??????? System.out.println("Result:"+rset.getString(1));
??? } catch (SQLException sqlEx)???? {
??? } finally {
????? try {
??????? System.out.println("Closing Statment & ResultSet Objects");
??????? if (rset != null) rset.close();
??????? if (stmt != null) stmt.close();
??????? if (conn != null) {
????????? System.out.println("Disconnecting...");
????????? conn.close();
????????? System.out.println("Disconnected from Database");
??????? }
????? } catch (Exception e) { }
??? }
}
}
??? 将文件保存为 CacheTest.java,然后编译代码:
$ORACLE_HOME/jdk/bin/javac CacheTest.java??? 现在,执行编译后的类:
$ORACLE_HOME/jdk/bin/java -classpath .:$ORACLE_HOME/jdbc/lib/ojdbc5.jar CacheTest??? 多执行几次。几次执行之后,您可以发现客户端已通过动态视图对值进行了缓存,如下所示:
select * from client_result_cache_stats$??? 客户端查询结果缓存在查找很少改变的表时十分有用。(即使它们更改,也会刷新缓存。)这与 SQL 结果缓存不同,其缓存位于服务器上。由于客户端缓存了结果,因此不需要在客户端与服务器间往返以获取数据 — 这不但节省了网络带宽,还节省了服务器 CPU 周期。