11g新特性-查询缓存(1)
众所周知,访问内存比访问硬盘快得多,除非硬盘体系发生革命性的改变。可以说缓存在Oracle里面无处不在,结果集缓存(Result Cache)是Oracle Database 11g新引入的功能,引入它的目的在于可以重用相同的结果集,减少逻辑IO,提高系统性能。结果集缓存又分为:服务端缓存和客户端缓存。
一、服务端缓存
1.服务器端的Result Cache Memorey由两部分组成。
(1)SQL Query Result Cache:存储SQL查询的结果集。
(2)PL/SQL Function Result Cache:用于存储PL/SQL函数的结果集。
2.相关的初始化参数:
SQL> show parameter result
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
client_result_cache_lag big integer 3000
client_result_cache_size big integer 0
result_cache_max_result integer 5
result_cache_max_size big integer 10M
result_cache_mode string MANUAL
result_cache_remote_expiration integer 0
带client的是客户端的参数,剩下的是服务端的相关参数。
2.1 首先,服务端的结果集缓存的开关,是参数result_cache_max_size。当result_cache_max_size=0的时候,代表不启用结果集缓存。
它的大小,默认值取决于其它内存设置(memory_target的0.25% 或sga_target 的0.5% 或shared_pool_size 的1%)
2.2 其次,result_cache_mode 用于控制Server Result cache的模式
result_cache_mode 有3个值:auto、manual、force
如果设置的值为MANUAL,用户必须用reslut_cache 提示才可以缓存结果集。
如果设置为FORCE,ORACLE会缓冲所有的结果,除非用户用了no_result_cache提示。
如果设置为AUTO,优化器会自动判断是否将查询结果缓存。
2.3 RESULT_CACHE_MAX_RESULT
该参数是控制单个result所能占据RESULT_CACHE_MAX_SIZE的大小比例,注意是一个百分比。
该参数默认是是5%,取值范围当然是1% ~ 100% 了。
2.4 result_cache_remote_expiration
该参数的作用是根据远程数据库对象设置缓存过期的时间,默认值为0.
也就是说,默认情况下,远程数据库对象不会被进行cache的。
3.相关视图
V$RESULT_CACHE_STATISTICS:列出各种缓存设置和内存使用统计数据。
V$RESULT_CACHE_MEMORY:列出所有的内存块和相应的统计信息。
V$RESULT_CACHE_OBJECTS:列出所有的对象(缓存的结果和依赖的对象)和它们的属性。
V$RESULT_CACHE_DEPENDENCY:列出缓存的结果和依赖对象间的依赖详情。
4.Oracle还提供了一个包来管理server result cache:dbms_result_cache
4.1查看server result cache的内存使用报告
SQL> set serveroutput on;
SQL> exec dbms_result_cache.Memory_Report
R e s u l t C a c h e M e m o r y R e p o r t
[Parameters]
Block Size = 1K bytes
Maximum Cache Size = 10M bytes (10K blocks)
Maximum Result Size = 512K bytes (512 blocks)
[Memory]
Total Memory = 110476 bytes [0.018% of the Shared Pool]
... Fixed Memory = 12080 bytes [0.002% of the Shared Pool]
... Dynamic Memory = 98396 bytes [0.016% of the Shared Pool]
....... Overhead = 65628 bytes
....... Cache Memory = 32K bytes (32 blocks)
........... Unused Memory = 0 blocks
........... Used Memory = 32 blocks
............... Dependencies = 1 blocks (1 count)
............... Results = 31 blocks
................... SQL = 1 blocks (1 count)
................... Invalid = 30 blocks (30 count)
PL/SQL procedure successfully completed.
4.2 FLUSH: 清空整个结果缓存的内容。
4.3 INVALIDATE: 使结果缓存中一个特定对象的缓存结果无效。
4.4 INVALIDATE_OBJECT: 根据缓存ID使一特定结果缓存无效。
5.实验:
SQL> create table test as select * from dba_objects; Table created. SQL> select /*+ result_cache */ owner,count(*) from test group by owner; rows selected. Execution Plan ---------------------------------------------------------- -------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------- ():: | | RESULT CACHE | 6fpdv8pg615sh5j0pw1t1jn3wq | | | | | ():: | ():: | -------------------------------------------------------------------------------------------------- Result Cache Information (identified by operation id): ------------------------------------------------------ ; dependencies=(TEST.TEST); parameters=(nls); name="select /*+ result_cache */ owner,count(*) from test group by owner" Note ----- ) Statistics ---------------------------------------------------------- recursive calls db block gets consistent gets physical reads redo size bytes sent via SQL*Net to client bytes received via SQL*Net from client SQL*Net roundtrips to/from client sorts (memory) sorts (disk) rows processed SQL> select /*+ result_cache */ owner,count(*) from test group by owner; rows selected. Execution Plan ---------------------------------------------------------- -------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------- ():: | | RESULT CACHE | 6fpdv8pg615sh5j0pw1t1jn3wq | | | | | ():: | ():: | -------------------------------------------------------------------------------------------------- Result Cache Information (identified by operation id): ------------------------------------------------------ ; dependencies=(TEST.TEST); parameters=(nls); name="select /*+ result_cache */ owner,count(*) from test group by owner" Note ----- ) Statistics ---------------------------------------------------------- recursive calls db block gets consistent gets physical reads redo size bytes sent via SQL*Net to client bytes received via SQL*Net from client SQL*Net roundtrips to/from client sorts (memory) sorts (disk) rows processed
从执行计划中可以看到标黄色的地方,就是对应 v$result_cache_objects的cache_id的。在第二次查询的执行计划中,发现逻辑读已经变成0 了,说明result cache起作用了。
SQL> exec dbms_result_cache.memory_report R e s u l t C a c h e M e m o r y R e p o r t [Parameters] Block Size = 1K bytes Maximum Cache Size = 10M bytes (10K blocks) Maximum Result Size blocks) [Memory] Total Memory bytes [0.018% of the Shared Pool] ... Fixed Memory bytes [0.002% of the Shared Pool] ... Dynamic Memory bytes [0.016% of the Shared Pool] ....... Overhead bytes ....... Cache Memory blocks) ........... Unused Memory blocks ........... Used Memory blocks ............... Dependencies blocks ( count) ............... Results blocks ................... SQL blocks ( count) ................... Invalid blocks ( count) PL/SQL procedure successfully completed. SQL> select * from v$result_cache_statistics; ID NAME VALUE ---------- ------------------------------ ------------------------------ Block Size (Bytes) Block Block Result Size Maximum (Blocks) Find Invalidation Hash Chain Length rows selected. SQL>
再来看看相应的report和统计信息。
SQL> select * from v$result_cache_statistics; ID NAME VALUE ---------- ------------------------------ ------------------------------ Block Size (Bytes) Block Block Result Size Maximum (Blocks) Find Invalidation Hash Chain Length rows selected. SQL> select /*+ result_cache */ owner,count(*) from test group by owner; OWNER COUNT(*) ------------------------------------------------------------ ---------- LZQ OWBSYS_AUDIT MDSYS OUTLN TEST CTXSYS OLAPSYS FLOWS_FILES OWBSYS SYSTEM OWNER COUNT(*) ------------------------------------------------------------ ---------- ORACLE_OCM EXFSYS APEX_030200 SCOTT ISC DBSNMP ORDSYS ORDPLUGINS SYSMAN SURE APPQOSSYS OWNER COUNT(*) ------------------------------------------------------------ ---------- XDB ORDDATA SS SYS WMSYS SI_INFORMTN_SCHEMA rows selected. SQL> select * from v$result_cache_statistics; ID NAME VALUE ---------- ------------------------------ ------------------------------ Block Size (Bytes) Block Block Result Size Maximum (Blocks) Find Invalidation Hash Chain Length rows selected. SQL>
注意到Find Count = 1,说明上次缓存的结果被后面的查询应用了一次。如果继续执行该查询,可以发现该统计信息会相应增加。
我们可以根据cache_id去 v$result_cache_objects查询相关的信息
SQL> select name,cache_id from v$result_cache_objects t where t.CACHE_ID='6fpdv8pg615sh5j0pw1t1jn3wq' ; NAME ------------------------------ CACHE_ID --------------------------------------------------------------------------------------------------- select /*+ result_cache */ own er,count(*) from test group by owner 6fpdv8pg615sh5j0pw1t1jn3wq
6.深入认识result cache
query cache result特性所占据的内存是从sga的share pool中分配,如下视图可以看到
SQL> select * from v$sgastat where lower(name) like '%result%';
POOL NAME BYTES
------------------------ ------------------------- ----------
shared pool Result Cache: State Objs 5492
shared pool Result Cache 98396
shared pool Result Cache: Memory Mgr 124
shared pool Result Cache: Bloom Fltr 2048
shared pool Result Cache: Cache Mgr 4416
result cache也有类似enqueue/lock的保护机制,RC enqueue就是拿来保护并发修改的。result cache依赖是object level的,
既不是row level的,也不是block level的。任何DML/DDL(甚至包括grant)都会使基于这个object的result cache变为invalidate。
所以result cache只有对那些在平时几乎没有任何DML的只读表比较有用,可以减轻io的压力。
在平时读取阶段不是使用的shared pool latch,而是使用的result cache latch,如下所示
SQL> select * from v$latchname where name like 'Result Cache%';
LATCH# NAME HASH
---------- ------------------------- ----------
391 Result Cache: RC Latch 1054203712
392 Result Cache: SO Latch 986859868
393 Result Cache: MB Latch 995186388
检查result cache配置是否生效
1.select dbms_result_cache.status from dual;
2.dbms_result_cache.MEMORY_REPORT
3.查看sql执行计划中是否还有关键字:result cache
注意:
11g的active dataguard的备库是不能使用result cache的,result cache目前可以使用在单节点主库和rac环境。
二、客户端查询结果集缓存
假设有这样一个情形:客户端需要通过慢速网络链接调用同一数据。尽管数据库可以立即将结果从缓存发送到客户端,但结果必须通过线路传送到客户端,这就增加了整体执行时间。现在有一些专门的中间件框架(如 Oracle Coherence),用于在 Java、PHP 和 Ruby 中缓存数据,如果有一个在客户端级别缓存数据的通用方法,又将如何呢?
为此,Oracle 数据库 11g 提供了“客户端查询结果缓存”。所有使用 OCI8 驱动程序的数据库客户端堆栈(C、C++、JDBC-OCI 等)都可以使用这一新特性,使客户端能够在本地缓存 SQL 查询的结果,而不是在服务器上。总言之,客户端查询结果缓存可以提供以下好处:
(1)使应用程序开发人员不用构建由所有会话共享的一致的每一流程的 SQL 结果缓存
(2)通过利用更便宜的客户端内存并在本地缓存每个应用程序的工作集,将服务器端查询缓存扩展到客户端内存,
(3)从而消除到服务器的往返过程,确保更好的性能
(4)通过节约服务器资源,改善服务器可伸缩性
(5)提供透明的缓存管理:内存管理、结果集的并发访问等
(6)透明地维护缓存与服务器端更改的一致性
(7)在 RAC 环境中提供一致性
要使用这一特性,所要做的就是设置一个初始化参数:CLIENT_RESULT_CACHE_SIZE = 1G
该参数定义客户端缓存为 1GB,这是所有客户端的总缓存大小。(这是一个静态参数,因此必须重启数据库来设置)可以在每个客户端中设置缓存,在客户端位置的 SQLNET.ORA 文件中指定其他参数:
让我们看一看它的使用方式。这是简单的 Java 代码,它使用 OCI8 驱动程序连接到数据库,然后执行 SQL 语句:select /*+ result_cache */ * from customers。提示致使语句缓存该结果(其他参数已经设置好)。
public class CacheTest { private String jdbcURL = "jdbc:oracle:oci8:@orcl"; private Connection conn = null; public CacheTest( ) throws ClassNotFoundException { Class.forName("oracle.jdbc.driver.OracleDriver"); } public static void main(String[] args) throws ClassNotFoundException, SQLException { CacheTest check = new CacheTest(); check.dbconnect(); check.doSomething(); } public void dbconnect() throws SQLException { System.out.println("Connecting with URL="+jdbcURL+" as arup/arup"); 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) {} } } }
PS: OCI8类似于thin,只是它需要在相关的服务器上装上oracle client才能使用。
11g新特性-查询缓存(1)的更多相关文章
- 11g新特性-自动sql调优(Automatic SQL Tuning)
11g新特性-自动sql调优(Automatic SQL Tuning) 在Oracle 10g中,引进了自动sql调优特性.此外,ADDM也会监控捕获高负载的sql语句. 在Oracle 11g中, ...
- Oracle 11g 新特性 – HM(Hang Manager)简介
在这篇文章中我们会对oracle 11g 新特性—hang 管理器(Hang Manager) 进行介绍.我们需要说明,HM 只在RAC 数据库中存在. 在我们诊断数据库问题的时候,经常会遇到一些数据 ...
- Spring4.1新特性——Spring缓存框架增强(转)
目录 Spring4.1新特性——综述 Spring4.1新特性——Spring核心部分及其他 Spring4.1新特性——Spring缓存框架增强 Spring4.1新特性——异步调用和事件机制的异 ...
- 11g新特性与12c新特性
1. 11g新特性概图 管理新特性> 开发新特性> 2. 12c 新特性概图
- 使用Oracle 11g新特性 Active Database Duplication 搭建Dataguard环境
Duplication Database 介绍 Duplicate database可以按照用途分为2种: duplicate database(复制出一个数据库) duplicate standby ...
- Oracle 11g 新特性 --SQL Plan Management 说明
Oracle 11g 新特性 --SQL Plan Management 说明 参见大神博主文章: http://blog.csdn.net/tianlesoftware/article/detail ...
- 11G 新特性之 密码延迟认证
11G 新特性之 密码延迟认证 11G 新特性之 密码延迟认证 Table of Contents 1. 特性简述 2. 特性潜在引发问题 3. 关闭特性 1 特性简述 为了防止用户密码的暴力破解,从 ...
- Oracle 11g新特性
文章转自网络 Oracle 11g于2007年7月11日美国东部时间11时(北京时间11日22时)正式发布,11g是甲骨文公司30年来发布的最重要的数据库版本,根据用户的需求实现了信息生命周期管理(I ...
- 11g新特性-概述 (转)
一.新特性提纲 1.数据库管理部分 ◆数据库重演(Database Replay) 这一特性可以捕捉整个数据的负载,并且传递到一个从备份或者standby数据库中创建的测试数据库上,然后重演负责以测试 ...
随机推荐
- 冰冻三尺非一日之寒--rabbitMQ,redis
第11章 1.rabbitMQ 2. redis 一.rabbitMQ: 人们写了有好多好多的开源的MQ服务器.其中大多数都是写出来用来解决特定问题的.它们不关心上面跑的是什么类型的消息,设计思想 ...
- 数据结构图文解析之:栈的简介及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- 一、Daily Scrum Meeting【Alpha】------Clover
[Alpha]Daily Scrum Meeting 第一次 [Alpha]Daily Scrum Meeting 第二次 [Alpha]Daily Scrum Meeting 第三次 [Alpha] ...
- Linux 下EXT2文件系统 —— 如何将蚂蚁和大象优雅的装进冰箱里
这一阵子真是偷懒,无时无刻不和自己身体中的懒癌做斗争.最终我还是被打败了,星期天两天几乎都是荒废过去的,在空闲的时候实际上我内心也是有点焦虑的,不知道去怎么度过这时间.学习吧又不想学习,看电视娱乐吧也 ...
- iOS plist文件创建
iOS中plist的创建,数据写入与读取功能创建一个test.plist文件,textInput作为输入,displayLabel作为显示,有一个按钮来触发保持程序triggerStorage: -( ...
- easyUi load方法重新加载表单的数据
1.表单回显数据的方法 <script> //方法一 function loadLocal(){ $('#ff').form('load',{ name:'myname', email:' ...
- 使用mosh取代ssh提高n2n网络连接稳定性
上文实现了远程n2n访问树莓派,但是ssh协议在网络状况不好的时候命令会卡住.这里发现了一个mosh协议,可以增强稳定性,使用后效果明显. 背景:使用n2n之后,在比较差的网络环境下,经常会被time ...
- Java Web笔记之Servlet(1)
今天在学习Servlet时,使用浏览器显示的网页效果与预期的有差异,仔细查找发现实<!DOCTYPE>声明的问题,截图如下: 代码如下: package secondServlet; im ...
- Linux 命令行总结
1.使用ln不加参数,会创建硬链接,如果要创建软连接,需要加-s 参数. # ln test1 test8 -rw-r--r-- root root Nov : test1 -rw-r--r-- ro ...
- Linux进程间通信(七):消息队列 msgget()、msgsend()、msgrcv()、msgctl()
下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信 -- 使用命名管道 一.什么是消息队列 消息队列提 ...