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

Oracle 11g新特性:Result Cache

原创 Eygle 2019-07-24
2208

结果集缓存(Result Cache)是Oracle Database 11g新引入的功能,除了可以在服务器端缓存结果集(Server Result Cache)之外,还可以在客户端缓存结果集(Client Result Cache)。下面着重介绍一下服务器端结果集缓存。

服务器端的Result Cache Memory由两部分组成。

l SQL Query Result Cache:存储SQL查询的结果集。

l PL/SQL Function Result Cache:用于存储PL/SQL函数的结果集。

Oracle通过一个新引入初始化参数result_cache_max_size来控制该Cache的大小。如果result_cache_max_size=0则表示禁用该特性。参数result_cache_max_result则控制单个缓存结果可以占总的Server Result Cache大小的百分比。

SQL> select * from v$version where rownum <2;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
SQL> show parameter result_cache
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 1280K
result_cache_mode                    string      MANUAL
result_cache_remote_expiration       integer     0

上面显示的参数中result_cache_mode用于控制Server result cache的模式,该参数有3个可选设置。

l 设置auto:则优化器会自动判断是否将查询结果缓存。

l 设置manual:则需要通过查询提示result_cache来告诉优化器是否缓存结果。

l 设置force :则尽可能地缓存查询结果(通过提示no_result_cache可以拒绝缓存)。

下面通过测试来看一下这一新特性的使用及优势所在,首先创建一张测试表:

SQL> connect eygle/eygle
Connected.
SQL> create table eygle as select * from dba_objects;
Table created.

在以前版本中,第一次执行该SQL可以看到consistent gets和physical reads大致相同:

    SQL> set autotrace on
    SQL> select count(*) from eygle;
      COUNT(*)
    ----------
        15993
    Statistics
    ----------------------------------------------------------
            28  recursive calls
              0  db block gets
            282  consistent gets
            217  physical reads

再次执行同样查询时,由于数据Cache在内存中,physical reads会减少到0,但是consistent gets很难降低:

   SQL> select count(*) from eygle;
      COUNT(*)
    ----------
        15993
    Statistics
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
            221  consistent gets
              0  physical reads

现在再来看看在Server Result Cache下Oracle的行为,首先在result_cache_mode参数设置为MANUAL时:

SQL> show parameter result_cache_mode
NAME                                TYPE        VALUE
------------------------------------ ----------- ------------------------------
result_cache_mode                    string      MANUAL

需要在SQL语句中手工指定Cache,这需要通过加入一个hints来实现,这个hints是result_cache:

SQL> select /*+ result_cache */ count(*) from eygle;
  COUNT(*)
----------
    15993
Execution Plan
----------------------------------------------------------
Plan hash value: 3602634261
-----------------------------------------------------------------------------------------
| Id  | Operation          | Name                      | Rows  | Cost (%CPU)| Time    |
-----------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT    |                            |    1 |    64  (0)| 00:00:01 |
|  1 |  RESULT CACHE      | 76rwwyazv6t6c39f1d8rrqh8rb |      |            |          |
|  2 |  SORT AGGREGATE    |                            |    1 |            |          |
|  3 |    TABLE ACCESS FULL| EYGLE                      | 14489 |    64  (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Result Cache Information (identified by operation id):
------------------------------------------------------
  1 - column-count=1; dependencies=(EYGLE.EYGLE);
  attributes=(single-row); name="select /*+ result_cache */ count(*) from eygle"
 
Statistics
----------------------------------------------------------
          4  recursive calls
          0  db block gets
        280  consistent gets
          0  physical reads

注意到这个执行计划已经和以往的不同,RESULT CACHE以76rwwyazv6t6c39f1d8rrqh8rb名称创建。那么在接下来的查询中,这个Result Cache就可以被利用:

SQL> select /*+ result_cache */ count(*) from eygle;
  COUNT(*)
----------
    15993
Execution Plan
----------------------------------------------------------
Plan hash value: 3602634261
 
-----------------------------------------------------------------------------------------
| Id  | Operation          | Name                      | Rows  | Cost (%CPU)| Time    |
-----------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT    |                            |    1 |    64  (0) | 00:00:01 |
|  1 |  RESULT CACHE       | 76rwwyazv6t6c39f1d8rrqh8rb |      |            |          |
|  2 |  SORT AGGREGATE     |                            |    1 |            |          |
|  3 |    TABLE ACCESS FULL| EYGLE                      | 14489|    64  (0)| 00:00:01  |
-----------------------------------------------------------------------------------------
Result Cache Information (identified by operation id):
------------------------------------------------------
  1 - column-count=1; dependencies=(EYGLE.EYGLE);
  attributes=(single-row); name="select /*+ result_cache */ count(*) from eygle"
 
Note
-----
  - dynamic sampling used for this statement
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size

在这个利用到Result Cache的查询中,consistent gets减少到0,直接访问结果集,不再需要执行SQL查询。这就是Result Cache的强大之处。

在以上测试中,当result_cache_mode设置为MANUAL时,只有使用hints的情况下,Oracle才会利用缓存结果集;而如果将result_cache_mode设置为AUTO,Oracle如果发现缓冲结果集已经存在,那么就会自动使用。但是如果缓冲结果集不存在,Oracle并不会自动进行缓冲,只有使用HINT的情况下,Oracle才会将执行的结果集缓存。

可以通过查询v$result_cache_memory视图来看Cache的使用情况:

SQL> select * from V$RESULT_CACHE_MEMORY
 2  where FREE='NO';
       ID      CHUNK    OFFSET FRE  OBJECT_ID  POSITION
--------- ---------- ---------- --- ---------- ----------
       0          0          0 NO          0          0
       1          0          1 NO          1          0

通过V$RESULT_CACHE_STATISTICS可以查询Result Cache的统计信息:

SQL> select * from V$RESULT_CACHE_STATISTICS;
        ID NAME                                VALUE
---------- ------------------------------ ----------
        1 Block Size (Bytes)                  1024
        2 Block Count Maximum                  992
        3 Block Count Current                   32
        4 Result Size Maximum (Blocks)          49
V$RESULT_CACHE_OBJECTS记录了Cache的对象:
SQL> SELECT ID,TYPE,NAME,BLOCK_COUNT,ROW_COUNT FROM V$RESULT_CACHE_OBJECTS;
        ID TYPE      NAME                           BLOCK_COUNT  ROW_COUNT
---------- ---------- ------------------------------ ----------- ----------
        0 Dependency EYGLE.EYGLE                              1          0
        1 Result    select /*+ result_cache */ cou            1          1
                      nt(*) from eygle

一个新的系统包被引入,DBMS_RESULT_CACHE可以用于执行关于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  = 992K bytes (992 blocks)
Maximum Result Size = 49K bytes (49 blocks)
[Memory]
Total Memory = 100836 bytes [0.059% of the Shared Pool]
... Fixed Memory = 5132 bytes [0.003% of the Shared Pool]
... Dynamic Memory = 95704 bytes [0.056% of the Shared Pool]
....... Overhead = 62936 bytes
....... Cache Memory = 32K bytes (32 blocks)
........... Unused Memory = 30 blocks
........... Used Memory = 2 blocks
............... Dependencies = 1 blocks (1 count)
............... Results = 1 blocks
................... SQL    = 1 blocks (1 count)
 
PL/SQL procedure successfully completed.


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论