Oracle 11g新特性:SQL Query Result Cache

时间:2021-01-12 20:23:28
Oracle Shared_Pool 中增加了 Server Result Cache 结构,新的 SQL query Result Cache 技术,解决了很多重复查询语句导致资源开销过大的典型问题!极大提高了查询效率。

 

SQL Query Result Cache:存储查询和查询片段的结果。

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

 

Result Cache技术适合的场景:

1) 查询的记录数很多,但返回结果数据较少的应用

2) 重复查询频度比较高

3) 数据相对静态,变化量不大

例如,数据仓库系统的各种统计运算就是比较典型的应用场景。

 

1、 Result Cache原理

存储SQL查询结果以备重用(跨语句、跨会话),如果数据发生改变,Result Cache中相应数据将变成INVALID状态,直到下次查询,再重新从硬盘取数据存储到Result Cache

 

Result cachebuffer 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函数。

2Result 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_size75%

注:需重启库生效,(SQL> select dbms_result_cache.status from dual;


--RESULT_CACHE_MAX_RESULT

         该参数为单个SQL查询语句设置可使用的最大Result Cache容量,

         缺省为RESULT_CACHE_MAX_SIZE5%

        

--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)和数据字典表

?  非确定的(NodeterministicPL/SQL函数

?  序列的CURRVALNEXTVAL

?  出现current_date, sysdate, sys_guid等函数

 

2.远程数据库上的DML/DDL 不会使高速缓存结果过期。

3.可高速缓存闪回查询。

4.结果高速缓存不会自动释放内存。

-它将不断增长,直到达到最大大小。

-DBMS_RESULT_CACHE.FLUSH 会清除内存。

 

5.绑定变量

 将使用变量值对高速缓存结果进行参数化。

 只能找到相同变量值的高速缓存结果。

 

6.对于以下情况,不会生成高速缓存结果:

 查询是基于数据的非当前版本构建的(强制实施读取一致性)

 当前会话在查询的表中存在未完成的事务处理

 

4Result Cache相关

Result CacheRAC

RAC支持Result Cache技术。RAC环境中的每个实例都有自己的Result Cache,每个实例的Result Cache不能共享,

即保存在Result Cache中的数据只能被本实例的应用进行访问。但是,一旦保存在某个Result Cache中的数据变成INVALID

则整个RAC环境中各Result Cache中的该数据都将变成INVALIDOracle通过专门的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环境。