SQL Query Result Cache:存储查询和查询片段的结果。
PL/SQL Function Result Cache:存储函数的结果集。
Result Cache技术适合的场景:
1) 查询的记录数很多,但返回结果数据较少的应用
2) 重复查询频度比较高
3) 数据相对静态,变化量不大
例如,数据仓库系统的各种统计运算就是比较典型的应用场景。
1、 Result Cache原理
存储SQL查询结果以备重用(跨语句、跨会话),如果数据发生改变,Result Cache中相应数据将变成INVALID状态,直到下次查询,再重新从硬盘取数据存储到Result Cache。
Result cache与buffer cache的不同:
Buffer cache缓存的是数据,再次select需要到内存中访问并整理出结果集。
Result cache缓存的就是select结果!(即无需再大量逻辑读)
例如:
--从buffer cache读时,逻辑读始终是6,而使用Result Cache,每次逻辑读为0
SQL> select job_id,avg(min_salary) from jobs group by job_id; Execution Plan ---------------------------------------------------------- Plan hash value: 2795457283 ------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 19 | 228 | 2 (0)| 00:00:01 | | 1 | SORT GROUP BY NOSORT | | 19 | 228 | 2 (0)| 00:00:01 | | 2 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 228 | 2 (0)| 00:00:01 | | 3 | INDEX FULL SCAN | JOB_ID_PK | 19 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------------ Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 6 consistent gets 0 physical reads 0 redo size 888 bytes sent via SQL*Net to client 431 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 19 rows processed |
SQL> select /*+ RESULT_CACHE */ job_id,avg(min_salary) from jobs group by job_id;
Execution Plan ---------------------------------------------------------- Plan hash value: 2795457283 ------------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 19 | 228 | 2 (0)| 00:00:01 | | 1 | RESULT CACHE | gh2hs3c3kyq7q731frs1zgnpja | | | | | | 2 | SORT GROUP BY NOSORT | | 19 | 228 | 2 (0)| 00:00:01 | | 3 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 228 | 2 (0)| 00:00:01 | | 4 | INDEX FULL SCAN | JOB_ID_PK | 19 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------------------------------ Result Cache Information (identified by operation id): ------------------------------------------------------
1 - column-count=2; dependencies=(HR.JOBS); parameters=(nls); name="select /*+ RESULT_CACHE */ job_id,avg(min_salary) from jobs group by job_id"
Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 888 bytes sent via SQL*Net to client 431 bytes received via SQL*Net from client 3 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 19 rows processed |
物化视图和Result Cache不同:
1)MV把结果记录在硬盘上,是永久的记录,而Result Cache则存储在内存里。
当数据库关闭或者result cache空间不足,这些信息会被删除。
2)MV具有静态特性,当query_rewrite_integrity=stale_tolerated时,如果不手动刷新MV,用户通过MV查询到的数据可能会不正确。
而Sql Result Cache存储的sql发生变化时,cache刷新是不可避免的。
3)Result Cache的限制:系统表和临时表、sequence.nextval, sequence.currval、sysdate、systimestamp、所有非确定性Pl/Sql函数。
2、Result Cache使用
1) 初始化参数
--RESULT_CACHE_MODE
? MANUAL: 使用RESULT_CACHE hint 方式来指定结果存储到Result cache中。(缺省值)
? FORCE: 所有结果都存储到Result Cache中。(不建议采取该策略!)
--RESULT_CACHE_MAX_SIZE
该参数设置Result Cache的最大容量。如果设置为0,则将关闭Result Cache功能。该参数的缺省值,依赖于内存管理模式和相关参数配置。例如:
? 当只设置memory_target参数时,RESULT_CACHE_MAX_SIZE = memory_target*0.25%。
? 当设置sga_target参数时,RESULT_CACHE_MAX_SIZE = sga_target*0.5%。
? 当设置shared_pool_size参数时,RESULT_CACHE_MAX_SIZE = shared_pool_size*1%。
该参数最大不能超过shared_pool_size的75%。
注:需重启库生效,(SQL> select dbms_result_cache.status from dual;)
--RESULT_CACHE_MAX_RESULT
该参数为单个SQL查询语句设置可使用的最大Result Cache容量,
缺省为RESULT_CACHE_MAX_SIZE的5%。
--RESULT_CACHE_REMOTE_EXPIRATION
该参数表示当SQL语句访问远程数据库对象时,允许远程对象数据发生变化的过期时间。
缺省值为0,表示一旦远程对象数据发生变化,相关查询的Result Cache数据变为INVALID。
2) 使用
--加hint使用
select /*+ RESULT_CACHE */ job_id,avg(min_salary) from jobs group by job_id;
select /*+ NO_RESULT_CACHE */ job_id,avg(min_salary) from jobs group by job_id;
--子查询中使用hint
即存储查询片段到Result Cache,不会受外围条件变化的影响。
--表级控制使用Result Cache
CREATE TABLE jobs (...) RESULT_CACHE (MODE DEFAULT);
ALTER TABLE jobs RESULT_CACHE (MODE FORCE);
SQL> select owner,table_name,result_cache from dba_tables where table_name='JOBS';
OWNER TABLE_NAME RESULT_CACHE -------------------- ----------------------- --------------------- HR JOBS FORCE |
3)管理
==包的使用
--Result Cache状态查询:
SQL> SELECT DBMS_RESULT_CACHE.STATUS FROM DUAL;
STATUS -------------------------------------------------------------------------------- ENABLED
|
--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 = 2304K bytes (2304 blocks) Maximum Result Size = 115K bytes (115 blocks) [Memory] Total Memory = 103532 bytes [0.042% of the Shared Pool] ... Fixed Memory = 5180 bytes [0.002% of the Shared Pool] ... Dynamic Memory = 98352 bytes [0.040% of the Shared Pool] ....... Overhead = 65584 bytes ....... Cache Memory = 32K bytes (32 blocks) ........... Unused Memory = 29 blocks ........... Used Memory = 3 blocks ............... Dependencies = 1 blocks (1 count) ............... Results = 2 blocks ................... Invalid = 2 blocks (2 count)
PL/SQL procedure successfully completed. |
--清空Result Cache
SQL> exec DBMS_RESULT_CACHE.FLUSH;
PL/SQL procedure successfully completed.
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 = 2304K bytes (2304 blocks) Maximum Result Size = 115K bytes (115 blocks) [Memory] Total Memory = 5180 bytes [0.002% of the Shared Pool] ... Fixed Memory = 5180 bytes [0.002% of the Shared Pool] ... Dynamic Memory = 0 bytes [0.000% of the Shared Pool]
PL/SQL procedure successfully completed. |
--将指定表的Result Cache设置为INVALID
SQL> exec DBMS_RESULT_CACHE.INVALIDATE('HR','JOBS'); |
==视图的使用
--查询Result Cache内存统计信息
SQL> select * from v$result_cache_statistics; ID NAME VALUE --- ----------------------------------- ------------------------------ 1 Block Size (Bytes) 1024 2 Block Count Maximum 2304 3 Block Count Current 32 4 Result Size Maximum (Blocks) 115 5 Create Count Success 1 6 Create Count Failure 0 7 Find Count 0 8 Invalidation Count 0 9 Delete Count Invalid 0 10 Delete Count Valid 0 11 Hash Chain Length 1 12 Find Copy Count 0
12 rows selected. |
--查看Result cache内存块的相关统计信息
select * from v$result_cache_memory; |
--显示Result Cache中缓存的对象,包括结果集和依赖的表相关数据
select * from v$result_cache_objects;<span color:navy;"="" style="word-wrap: break-word; font-size: 10pt;">
|
--查询结果集数据与依赖表的关联关系
select * from v$result_cache_dependency; |
3、注意事项如下:
1.Result Cache局限(不支持) ? 系统临时表(Temporary Table)和数据字典表 ? 非确定的(Nodeterministic)PL/SQL函数 ? 序列的CURRVAL、NEXTVAL ? 出现current_date, sysdate, sys_guid等函数
2.远程数据库上的DML/DDL 不会使高速缓存结果过期。 3.可高速缓存闪回查询。 4.结果高速缓存不会自动释放内存。 -它将不断增长,直到达到最大大小。 -DBMS_RESULT_CACHE.FLUSH 会清除内存。
5.绑定变量 – 将使用变量值对高速缓存结果进行参数化。 – 只能找到相同变量值的高速缓存结果。
6.对于以下情况,不会生成高速缓存结果: – 查询是基于数据的非当前版本构建的(强制实施读取一致性) – 当前会话在查询的表中存在未完成的事务处理 |
4、Result Cache相关
Result Cache与RAC
RAC支持Result Cache技术。RAC环境中的每个实例都有自己的Result Cache,每个实例的Result Cache不能共享, 即保存在Result Cache中的数据只能被本实例的应用进行访问。但是,一旦保存在某个Result Cache中的数据变成INVALID, 则整个RAC环境中各Result Cache中的该数据都将变成INVALID。Oracle通过专门的RCBG进程,处理RAC环境下Result Cache之间的数据同步。 |
Result Cache与并行处理
并行处理也支持Result Cache技术。在并行查询中,整个查询结果集将被保存在Result Cache中, 也就是说,整个并行查询语句方可使用Result Cache中的查询结果,单个并行查询子进程无法访问Result Cache。 在RAC环境下,并行查询结果保存在查询协调进程(Query Coordinator)所在实例的Result Cache中。 |
5、客户端Result Cache技术
暂略。。。
6 常用查询表
V$RESULT_CACHE_STATISTICS:列出服务端缓存设置和内存使用的统计信息
V$RESULT_CACHE_MEMORY:列出所有服务端内存块缓存和相应的统计结果
V$RESULT_CACHE_OBJECTS:列出服务端缓存的对象,以及属性
V$RESULT_CACHE_DEPENDENCYL:列出服务端缓存依赖的细节
CLIENT_RESULT_CACHE_STATS$
DBA_TABLES, USER_TABLES, ALL_TABLES
SELECT NAME, VALUE FROM V$RESULT_CACHE_STATISTICS; --列出服务端缓存的统计信息
SELECT STAT_ID, SUBSTR(NAME,1,20), VALUE, CACHE_ID FROM CLIENT_RESULT_CACHE_STATS$ ORDER BY CACHE_ID, STAT_ID; --监控客户端缓存的统计信息
检查result cache配置是否生效
1.select dbms_result_cache.status from dual;
2.dbms_result_cache.MEMORY_REPORT
3.查看sql执行计划
注意:
11g的active dataguard的备库是不能使用result cache的,这是oracle的一个bug,因为涉及到内码的问题,所以oracle一直没有修复,result cache目前可以使用在单节点主库和rac环境。
关于这个新特性的参考链接:
http://docs.oracle.com/cd/E11882_01/server.112/e41573/memory.htm#PFGRF983
http://www.ningoo.net/2007/08/22/oracle11g_new_feature_server_result_cache2.htm
http://yangtingkun.itpub.net/post/468/391015
http://yangtingkun.itpub.net/post/468/391560
检查result cache配置是否生效
1.select dbms_result_cache.status from dual;
2.dbms_result_cache.MEMORY_REPORT
3.查看sql执行计划
注意:
11g的active dataguard的备库是不能使用result cache的,这是oracle的一个bug,因为涉及到内码的问题,所以oracle一直没有修复,result cache目前可以使用在单节点主库和rac环境。