love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

Phone:18180207355 提供专业Oracle/MySQL/PostgreSQL数据恢复、性能优化、迁移升级、紧急救援等服务

11g新特性之–Query Cache Result 研究

本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

本文链接地址: 11g新特性之–Query Cache Result 研究

该特性是11gR1引入的,关于query result cache特性,主要有2种:

1. PL/SQL Function Result Cache –针对plsql而言
2. Query Result Cache –顾名思义针对重复执行的sql

我们都知道oracle通常是通过参数来进行控制某个功能的,当然这个也不例外,
首先我们来介绍跟该特性有关的几个参数(包括隐含参数):

几个重要的参数:

result_cache_mode
该参数是最为重要的,其属性有manual和force 两种。
manual是默认属性,也就是说我们要启用该特性,那么必须通过hint来实现,不然oracle的优化器
是无法认知的,那么是什么hint呢? 如下:

当设置为force时,oracle 优化就能自动识别了,不需要使用hint,相反,如果当设置为force时,同时
你又不想某个sql或应用使用该特性,那么可以使用NO_RESUIT_CACHE  hint来进行避规。
至于说,当启动该特性时,oracle是如何来实现的?这个问题需要进一步研究。
result_cache_max_size 
该参数控制着使用该特性的内存大小,当该参数设置为0,那么也就意味着关闭了该特性。
该部分内存是从SGA中分配的,至于分配的比例关系,metalink提供了如下的数据:
0.25% of MEMORY_TARGET or
0.5% of SGA_TARGET or
1% of SHARED_POOL_SIZE
上面的关系应该是一目了然了,如何解释?我暂且不说,给大家留个问题。
result_cache_max_result
该参数是控制单个result所能占据query cache的大小比例,注意是一个百分比。
该参数默认是是5%,取值范围当然是1% ~ 100% 了。
result_cache_remote_expiration
该参数的作用是根据远程数据库对象设置缓存过期的时间,默认值为0.
也就是说,默认情况下,远程数据库对象不会被进行cache的。

_result_cache_global
顾名思义,该参数肯定是针对Rac集群而设计的,这样可以大大的降低经典的gc等待。
下面通过相关的实验操作来进行详细的说明:

发现第一使用hint解析时,消耗较高,下面我们再次执行,看看结果。
大家注意前面的执行计划,红色部分,这里的意思可以理解为oracle首先在执行
该sql执行之前,会到query cache里面去寻找是否有这个sql语句的信息。
如果没有,那么将进行解析,跟以前的理解完全一样。
 

第2次执行,我们发现消耗非常小。这里大家可以跟前面执行的语句,
select owner,object_name from ht01 where object_id=888; 进行对比,即使执行过相同
的sql语句,再次执行,那么也仍然有4个逻辑读,为什么呢?答案就是软解析。
我们可以发现使用了query cache result特性后,逻辑读为0. 效率明显高很多。
这里为什么query cache result这么强大,其他他这里就是发现cache里面已经存在了,
那么连软解析就不用了,直接从cache里面返回结果给客户端。

下面我们将该参数设置为force,来看看情况如何。

到这里,或许有人会有点迷惑了,最开始执行的是object_id=888,后面执行是object_id为666,
为啥也能使用该特性且生效呢?因为query cache result特性不仅仅是根据文本来匹配,只要执行计划
或部分执行计划一样,那么就会共享,也就是说就能避免软解析直接返回结果。
这样要简单的提及一下的是,我知道mysql 也有query cache的特性,开始我以为oracle跟mysql这
功能完全一样,现在发现其实不一样,oracle 这里比mysql先进多了,为啥这么说呢? 因为mysql的
query cache 仅仅是对文本进行匹配,如果这里换成是mysql,那么object_id为666和888的2个sql语句,
是无法进行共享的,除非使用绑定变量。
到最后,可能有朋友为问道,如果使用了该特性,那么想过的几个视图记录的信息岂不是会不断变大吗?
确实是这样的,但是oracle提供了一个新的dbms包,可以对query cache result进行操作。

另外提及一下的是,如果你不想让某个sql不使用query cache result特性,而这时又无法用过
修改sql语句来加hint 时,那么此时你可以用过如下方式来进行操作:
exec DBMS_RESULT_CACHE.INVALIDATE_OBJECT(‘&CACHE_ID’); 如下例子

这里需要注意的是,如果result_cache_mode是设置为force的话,那么经过该过程的操作其实
是不起任何作用的,当该参数设置为auto了就ok了。
通过dbms_result_cache.memory_report来查看cache memory的使用情况:

通过dbms_result_cache.fulsh来清除已经cache的信息:

另外跟该特性相关的几个新引入的视图也跟大家简单的介绍一下,如下:

V$RESULT_CACHE_DEPENDENCY
该视图记录了result cache的一些对象,如下:

result_id其实就是执行计划中的id。 后面的object_no即是对象的object_id。

V$RESULT_CACHE_MEMORY
该视图主要是用来查询query cache的使用情况,如下:

V$RESULT_CACHE_OBJECTS
该视图主要是记录了关于cache 对象的一些信息,大家可以参考官方文档的说明,
该视图在11gR1和11gR2 中无任何差异,如下查询例子:

V$RESULT_CACHE_STATISTICS
该视图主要是记录result cache对象的一些统计信息,是记录的累计值。                                                                                 

到最后,我们再来看看query cache result特性有哪些局限,通俗的将就是在哪些情况下,
该特性将无法使用或将不会生效。 
Result cache is disabled for queries containing:
  Temporary or Dictionary tables
  Nondeterministic PL/SQL functions
  Sequence CURRVAL and NEXTVALSQL functions CURRENT_DATE,SYSDATE,SYS_GUID, and so on
DDL/DML on remote database does not expire cached results
Flashback queries can be cached
Result Cache does not automatically release memory
It grows until maximum size is reached
DBMS_RESULT_CACHE.FLUSH purges memory
Bind variables
   Cached result is parameterized with variable values
   Cached results can only be found for the same variable values
Cached result will not be build if:
   Query is build on a noncurrent version of data(read consistency enforcement)
   Current session has outstanding transaction on tables in query

Result cache is flushed when we flush the shared pool

关于该特性,大家可以参考如下metalink文档或查阅官方文档:
Complete Reference To 11g New Feature : SQL Query Result Cache [Video] [ID 1108133.1]
当你读完这篇文章以后,你或许会跟我一样,大脑中会有了一个很大的疑问:
query cache result特性所占据的这部分内存是如何管理的,虽然说该部分内存是从sga中分配,
那么该部分内存到底存在哪儿呢?cache buffer?还是shared pool中吗?如果是,
那么当执行如下是命令后还有用吗?

其实从上面红色部分我们可以看出,该部分内存存在shared pool中。至于是如何进行管理的,其结构如何?
将是下一篇文章所要阐述的。

备注:
  1. 由于plsql query cache result其实基本上差不多,只是11.1 和11.2有小小的差异,
所以我这里没有演示plsql query cache result。另外就是既然是新特性,那么就避免不了
有不少的bug,所以在使用该特性时需要做一定的权衡(经查metalink,相关的几个bug影响其实
不大)。
  2. query cache result除了server端之外还有client query cache result,也有一些相关的参数配置,如下:
client_result_cache_size
client_result_cache_lag
如下参数需要加到客户端sqlnet.ora中。
OCI_RESULT_CACHE_MAX_SIZE
OCI_RESULT_CACHE_MAX_RSET_SIZE
OCI_RESULT_CACHE_MAX_RSET_ROWS
 
更为详细的说明或用法以及注意事项,大家请参考官方文档,这里不做说明。 

5 Responses to “11g新特性之–Query Cache Result 研究”

  1. leo Says:

    这个特性oltp有用,OLAP没法用的。你写的挺详细。

  2. 11g新特性之–Query Cache Result 研究 – wiloon Says:
  3. 11g新特性之–Query Cache Result 研究 (1) - Oracle - 开发者第993841个问答 Says:

    […] 原帖地址:http://www.killdb.com/?p=205   为啥标题没有写是11gR1 还是R2?因为后面还有续集。 […]

  4. 11g 新特性之--query result cache ( 终结篇) - Oracle - 开发者第994377个问答 Says:

    […] 11g 新特性之–query result cache(1)   http://www.killdb.com/?p=205 […]

  5. 11g 新特性之–query result cache(2) - Oracle - 开发者第994393个问答 Says:

    […] 新特性之–query result cache 的第一篇文章中(http://www.killdb.com/?p=205),我讲述该特性的使用以及相关的管理等等, […]

Leave a Reply

You must be logged in to post a comment.