暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle数据库设置表的RESULT_CACHE

Oracle微学堂 2018-03-16
1504

result cache是oracle 11g新推出的特性,通过把查询结果缓存在内存中来提高查询性能。缓存分为clinet和server端缓存。本文主要讨论server端缓存。server result cache是shared pool的内存的一部分。结果缓存更适合于数据变化不频繁的系统,例如OLAP。简单原理如下:当sql执行时,数据库先去result cache去查找相关结果;当结果相关的对象发生变化,例如相关表的数据被删除一条,则结果缓存失效。


几个与result cache相关的参数

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 85024K
result_cache_mode                    string      FORCE
result_cache_remote_expiration       integer     0
SQL>

关于Server Result Cache的几个重要参数

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

SQL> SELECT name,version FROM v$sql_hint WHERE name LIKE '%RESULT%';
NAME                                                             VERSION
---------------------------------------------------------------- -------------------------
RESULT_CACHE                                                     11.1.0.6
NO_RESULT_CACHE                                                  11.1.0.6

当设置为force时,oracle 优化就能自动识别了,不需要使用hint,相反,如果当设置为force时,同时
你又不想某个sql或应用使用该特性,那么可以使用NO_RESUIT_CACHE  hint来进行避规。

当设置了auto时,优化器将根据大量因素决定是否缓存结果。决定因素包括查询执行的频率、生成结果的
成本以及针对底层数据库对象更改的频率,目前的稳定性还需要验证。

result_cache_max_size 
该参数控制着使用该特性的内存大小,当该参数设置为0,那么也就意味着关闭了该特性。
该部分内存是从SGA中分配的,Oracle11g都不会将RESULT_CACHE_MAX_SIZE设置为超过
SHARED_POOL_SIZE的75%,至于分配的比例关系,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等待。

和Result Cache相关的视图
SQL> select * from dict where table_name like '%RESULT_CACHE%';
TABLE_NAME                     COMMENTS
------------------------------ --------------------------------------------------------------------------------
CLIENT_RESULT_CACHE_STATS$     Synonym for CRCSTATS_$
GV$RESULT_CACHE_DEPENDENCY     Synonym for GV_$RESULT_CACHE_DEPENDENCY
GV$RESULT_CACHE_MEMORY         Synonym for GV_$RESULT_CACHE_MEMORY
GV$RESULT_CACHE_OBJECTS        Synonym for GV_$RESULT_CACHE_OBJECTS
GV$RESULT_CACHE_STATISTICS     Synonym for GV_$RESULT_CACHE_STATISTICS
V$RESULT_CACHE_DEPENDENCY      Synonym for V_$RESULT_CACHE_DEPENDENCY
V$RESULT_CACHE_MEMORY          Synonym for V_$RESULT_CACHE_MEMORY
V$RESULT_CACHE_OBJECTS         Synonym for V_$RESULT_CACHE_OBJECTS
V$RESULT_CACHE_STATISTICS      Synonym for V_$RESULT_CACHE_STATISTICS
9 rows
SQL>

V$RESULT_CACHE_STATISTICS:列出各种缓存设置和内存使用统计数据。
这个特殊说明下字段:
Create Count Success
:新建的result cache的数量
Find Count:说明使用result cache的次数
Create Count Failure:说明创建result cache失败的数量

V$RESULT_CACHE_MEMORY:列出所有的内存块和相应的统计信息。
V$RESULT_CACHE_OBJECTS:列出所有的对象(缓存的结果和依赖的对象)和它们的属性。
V$RESULT_CACHE_DEPENDENCY:列出缓存的结果和依赖对象间的依赖详情。

包dbms_result_cache管理server result cache

SQL> desc dbms_result_cache

Element           Type      
----------------- --------- 
STATUS_DISA       CONSTANT  
STATUS_ENAB       CONSTANT  
STATUS_BYPS       CONSTANT  
STATUS_SYNC       CONSTANT  
STATUS_CORR       CONSTANT  
STATUS            FUNCTION  
FLUSH             FUNCTION  
MEMORY_REPORT     PROCEDURE 
DELETE_DEPENDENCY FUNCTION  
INVALIDATE        FUNCTION  
INVALIDATE_OBJECT FUNCTION  
BYPASS            PROCEDURE 
SQL>

查看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  = 85024K bytes (85024 blocks)
Maximum Result Size = 4251K bytes (4251 blocks)
[Memory]
Total Memory = 87426840 bytes [5.428% of the Shared Pool]
 
... Fixed Memory = 68992 bytes [0.004% of the Shared Pool]
... Dynamic Memory = 87357848 bytes [5.424% of the Shared Pool]
....... Overhead = 293272 bytes
....... Cache Memory = 85024K bytes (85024 blocks)
........... Unused Memory = 0 blocks
........... Used Memory = 85024 blocks
............... Dependencies = 89 blocks (89 count)
............... Results = 84935 blocks
................... SQL     = 59063 blocks (46593 count)
................... Invalid = 25546 blocks (23785 count)
PL/SQL procedure successfully completed
SQL>
DBMS_RESULT_CACHE
功能和存储过程

STATUS存储过程
返回结果缓存的当前状态。值包括:
ENABLED:结果缓存是激活的。
DISABLED:结果缓存是不可用的。
BYPASSED:结果缓存暂时不可用。
SYNC: 结果缓存是可用的,但是目前正与其他RAC节点重新同步。
MEMORY_REPORT存储过程
 列出结果缓存内存利用的一个概要(默认)或详细的报表。
FLUSH存储过程
 
推出整个结果缓存的内容。
INVALIDATE存储过程
使结果缓存中一个特定对象的缓存结果无效。
INVALIDATE_OBJECT存储过程
根据缓存ID使一特定结果缓存无效。

深入认识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        66536
shared pool  Result Cache                 87357848
shared pool  Result Cache: Memory Mgr          200
shared pool  Result Cache: Cache Mgr           208
shared pool  Result Cache: Bloom Fltr         2048
SQL>

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
---------- ---------------------------------------------------------------- ----------
       405 Result Cache: RC Latch                                           1054203712
       406 Result Cache: SO Latch                                            986859868
       407 Result Cache: MB Latch                                            995186388

检查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环境。

课堂实验

SQL> select count(*) from t;

  COUNT(*)

----------

    13456

 SQL> set autot on;

SQL> select count(*) from t;

  COUNT(*)

----------

    13456

 ----------------------------------------------------------

Plan hash value: 2966233522

-------------------------------------------------------------------

| Id | Operation          | Name |Rows  | Cost (%CPU)| Time     |

-------------------------------------------------------------------

|   0| SELECT STATEMENT   |      |    1 |    50   (2)| 00:00:01 |

|   1|  SORT AGGREGATE    |     |     1 |            |          |

|   2|   TABLE ACCESS FULL| T    | 12278 |   50   (2)| 00:00:01 |

-------------------------------------------------------------------    

SQL> select *+ result_cache */ count(*)from t;

  COUNT(*)

----------

    13456

------------------------------------------------------------------------------------------

| Id | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------

|   0| SELECT STATEMENT    |                            |     1 |   50   (2)| 00:00:01 |

|   1|  RESULT CACHE       | c8ukugu9jf5474pjzn83wj3zph |       |           |          |

|   2|   SORT AGGREGATE    |                            |     1 |           |          |

|   3|    TABLE ACCESS FULL| T                          | 12278 |    50  (2)| 00:00:01 |

---修改为force,则强制使用resultcache

alter system set result_cache_mode=force;

 SQL> create table t1 as select * from t;

SQL> select count(*) from t1;

  COUNT(*)

----------

    13456

------------------------------------------------------------------------------------------

| Id | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------

|   0| SELECT STATEMENT    |                            |     1 |   50   (2)| 00:00:01 |

|   1|  RESULT CACHE       | 8q8qwtn4uk3vv7sm1ynpzz6t4k |       |           |          |

|   2|   SORT AGGREGATE    |                            |     1 |            |          |

|   3|    TABLE ACCESS FULL| T1                         | 14242 |    50  (2)| 00:00:01 |

------------------------------------------------------------------------------------------

 SQL> select count(*) from t1;

  COUNT(*)

----------

    13456

------------------------------------------------------------------------------------------

| Id | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------

|   0| SELECT STATEMENT    |                            |     1 |   50   (2)| 00:00:01 |

|   1|  RESULT CACHE       | 8q8qwtn4uk3vv7sm1ynpzz6t4k |       |            |          |

|   2|   SORT AGGREGATE    |                            |     1 |            |          |

|   3|    TABLE ACCESS FULL| T1                         | 14242 |    50  (2)| 00:00:01 |

------------------------------------------------------------------------------------------

 查询V$RESULT_CACHE_OBJECTS可以得到目前缓存的情况

  1*select name,cache_id from V$RESULT_CACHE_OBJECTS

SQL> select name,cache_id fromV$RESULT_CACHE_OBJECTS;


NAME                                                                  CACHE_ID

------------------------------------------------------------------------------------------------------------------------

WJ.T1                                                                 WJ.T1

WJ.T                                                                  WJ.T

select count(*) from t1                                               8q8qwtn4uk3vv7sm1ynpzz6t4k

select *+ result_cache */ count(*) fromt                            c8ukugu9jf5474pjzn83wj3zph


2,使用Table Annotations。 表注释的优先级低于sql语句。通过关键字RESULT_CACHE来实现。有DEFAULT和FORCE两个数值

DEFAULT

    If at least one table in a query is set to DEFAULT, then result cachingis not enabled at the table level for this query, unless the RESULT_CACHE_MODEinitialization parameter is set to FORCE or the RESULT_CACHE hint is specified.This is the default value.

 FORCE

    If all the tables of a query are marked as FORCE, then the query resultis considered for caching. The table annotation FORCE takes precedence over theRESULT_CACHE_MODE parameter value of MANUAL set at the session level.

 测试结果如下

 SQL> alter table t1 result_cache (MODEforce);   

 SQL> alter session set result_cache_mode= MANUAL;

 --查询T1使用resultcache

SQL> select count(*) from t1;

  COUNT(*)

----------

    13456

------------------------------------------------------------------------------------------

| Id | Operation           | Name                       | Rows  | Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------

|   0| SELECT STATEMENT    |                            |     1 |   50   (2)| 00:00:01 |

|   1|  RESULT CACHE       | 8q8qwtn4uk3vv7sm1ynpzz6t4k |       |           |          |

|   2|   SORT AGGREGATE    |                            |     1 |            |          |

|   3|    TABLE ACCESS FULL| T1                         | 14242 |    50  (2)| 00:00:01 |

------------------------------------------------------------------------------------------

--查询表T没有使用resultcache

SQL> select count(*) from t;

  COUNT(*)

----------

    13456

-------------------------------------------------------------------

| Id | Operation          | Name |Rows  | Cost (%CPU)| Time     |

-------------------------------------------------------------------

|   0| SELECT STATEMENT   |      |    1 |    50   (2)| 00:00:01 |

|   1|  SORT AGGREGATE    |     |     1 |            |         |

|   2|   TABLE ACCESS FULL| T    | 12278 |   50   (2)| 00:00:01 |

扫描二维码关注我的微学堂

搜索刘老师微信号:Rman-2014,备注“Oracle学习与咨询”,即可添加好友;或者扫描下面二维码,关注我的“微学堂”公众号,了解最新OCP认证动态、题库及答案解析、培训机构及讲师介绍、课堂授课内容等。每天还有一篇技术文章发布哦!



文章转载自Oracle微学堂,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论