合 Oracle优化中的结果集缓存
简介
结果集缓存(Result Cache)是Oracle 11g的新特性,用于存储经常使用的SQL语句和函数的查询结果。当相同语句再次执行的时候,Oracle就不用再次重复执行(包括扫描索引、回表、计算、逻辑读、物理读等操作),而是直接访问内存得到结果。结果集缓存可以将SQL语句查询的结果缓存在内存(SGA的Shared Pool)中,从而显著地改进需要多次执行和查询相同结果的SQL语句的性能。
结果集缓存的优点是可以重用相同的结果集,减少逻辑I/O,从而提高系统性能。结果集缓存最适合的是静态表(例如只读表),即结果集缓存最适合返回同样结果的查询。
若SQL语句中包含的对象(例如表)做了UPDATE,INSERT,DELETE或是DDL操作,则相关的所有SQL的缓存结果集就自动失效了。所以,Result Cache只对那些在平时几乎没有任何DML操作的只读表比较有用,可以减轻I/O的压力。
对于一些固定性的小的查询结果集或统计性的SQL语句(例如,SQL语句非常复杂,但是最终返回的结果集很简单,只包含少数的几行数据;或者一个非常复杂的SQL,包括好几个大表最后做了一个count操作只返回1行结果)可以使用结果集缓存(Result Cache)。对于一些常用的小表可以使用保留池(Keep Pool)。
在实际情况中,结果集缓存仅在少数的情况下是有效的。在以下情况中,结果集不会被缓存:
① 查询使用非确定性的函数、序列和临时表的结果集不会被缓存。
② 查询违反了读一致性时结果集将不会被缓存。
③ 引用数据字典视图的查询的结果集不会被缓存。
④ 查询结果集大于可用缓存结果集可用空间的不会被缓存。
⑤ 对依赖对象的任何改变(DML、DDL)都会使整个缓存的结果集变为无效,结果集缓存最适合那些只读或接近只读的表。
⑥ ADG的备库不能使用结果集缓存。
SQL语句中通过/*+ result_cache*/
提示实现result cache,pl/sql函数通过建函数时的result_cache子句实现。
分类
Oracle数据库引擎提供了3种结果集缓存,包括:服务器查询结果集缓存、PL/SQL函数结果集缓存和客户端结果集缓存。
(一)服务器查询结果集缓存
服务器查询结果集缓存由以下一些参数控制:
RESULT_CACHE_MODE:该参数用来控制结果集缓存的操作模式。
AUTO表示优化程序将根据重复的执行操作确定将哪些结果存储在高速缓存中。
MANUAL表示只有使用了RESULT_CAHCE提示的查询或对带有
RESULT_CACHE
属性的表访问的查询才会被缓存,MANUAL为该参数的默认值。FORCE表示所有合适的查询都会被缓存。
对于AUTO和FORCE设置,如果语句中包含
[NO_]RESULT_CACHE
提示,那么该提示优先于参数设置。RESULT_CACHE_MAX_SIZE:控制结果集缓存的大小,默认值取决于其它内存设置(MEMORY_TARGET的0.25%或SGA_TARGET的0.5%或SHARED_POOL_SIZE的1%)。当RESULT_CACHE_MAX_SIZE为0的时候,代表不启用结果集缓存。需要注意的是,若将该参数的值从0修改为非0值后,则需要重启数据库才能启用服务器查询结果集缓存特性,反之亦然。
RESULT_CACHE_MAX_RESULT:单个结果集能够消耗的缓存的最大百分比,比这个值大的结果集将不能被缓存,默认大小为RESULT_CACHE_MAX_SIZE的5%。
RESULT_CACHE_REMOTE_EXPIRATION:设置远程数据库结果集缓存过期的时间,以分钟为单位,默认值为0,表示不缓存远程数据库结果集。
与结果集缓存相关的一些视图:
V$RESULT_CACHE_STATISTICS:列出各种缓存设置和内存使用统计数据。
V$RESULT_CACHE_MEMORY:列出所有的内存块和相应的统计信息。
V$RESULT_CACHE_OBJECTS:列出所有的对象(缓存的结果和依赖的对象)和它们的属性。
V$RESULT_CACHE_DEPENDENCY:列出缓存的结果和依赖对象间的依赖详情。
与结果集缓存相关的包是DBMS_RESULT_CACHE。
STATUS函数:返回值若为DISABLED则表示没有开启结果集缓存;若为ENABLED则表示已经开启并且可以使用结果集缓存;若为BYPASS则表示已经开启结果集缓存但不可以使用结果集缓存,此时可以通过执行“EXEC DBMS_RESULT_CACHE.BYPASS(FALSE);”来使用结果集缓存。执行后如果返回值仍然是BYPASS,那么可能是参数RESULT_CACHE_MAX_SIZE的值为0的原因。STATUS函数返回值若为SYNC则表示结果缓存是可用的,但是目前正与其它RAC节点重新同步。可以使用SQL语句“SELECT DBMS_RESULT_CACHE.STATUS FROM DUAL;”来检查是否开启了结果集缓存机制。
MEMORY_REPORT存储过程:列出结果缓存内存利用的一个概要(默认)或详细的报表。如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | SYS@orclasm > set serveroutput on SYS@orclasm > 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 = 2816K bytes (2816 blocks) Maximum Result Size = 140K bytes (140 blocks) [Memory] Total Memory = 169328 bytes [0.034% of the Shared Pool] ... Fixed Memory = 5352 bytes [0.001% of the Shared Pool] ... Dynamic Memory = 163976 bytes [0.033% of the Shared Pool] ....... Overhead = 131208 bytes ....... Cache Memory = 32K bytes (32 blocks) ........... Unused Memory = 25 blocks ........... Used Memory = 7 blocks ............... Dependencies = 2 blocks (2 count) ............... Results = 5 blocks ................... SQL = 5 blocks (5 count) PL/SQL procedure successfully completed. |
FLUSH函数:清空整个结果缓存的内容。
INVALIDATE函数:使结果缓存中某个特定对象的缓存结果无效。
INVALIDATE_OBJECT函数:根据缓存ID使某个特定结果缓存无效。
可以在表级别设置RESULT_CACHE,如下所示:
1 | ALTER TABLE HR.EMPLOYEES RESULT_CACHE(MODE FORCE); |