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

Oracle 强制不可缓存的查询的结果缓存?

askTom 2016-12-13
2816

问题描述

是否有方法强制任何查询的结果缓存,并让应用程序处理无效?

在极端情况下(不太明智) ,请执行以下操作:

从dba_tables中选择/*+ force_result_cache */ * ,其中table ='XXX';

基本上,我们希望缓存复杂的查询(涉及多级视图、sysdate、'按级连接<= x'行生成器等)并在必要时让应用程序失效。结果缓存具有我们所需的基本功能: DB截取查询、比较绑定、返回预查询结果的能力。但它对缓存的内容限制太大,而且即使是显式重写,也不允许对陈旧数据进行任何容忍。当然,我理解其中的原因,而且它们完全合情合理,我只是在尝试将其应用扩展到我的应用程序中。

目前,我们有自己的缓存,使用类似于就地MV的东西。这样做很有效,但我们必须1)进行完全刷新,这非常耗时; 2)由于视图-视图依赖关系,因此必须按特定的顺序进行刷新。

如有任何建议或备选办法,将不胜感激。谢谢你抽出时间。

专家解答

我不明白您所说的“让应用程序处理无效”是什么意思。结果缓存完全由Oracle数据库管理。

第一次执行查询时, Oracle会将结果存储在高速缓存中。如果表中的数据发生更改,则会立即使缓存失效。

比如。我创建了一个函数,它休眠1秒以使增益清晰,并创建了一个包含10行的表:

create or replace function f (p int)
  return int as 
begin
  dbms_lock.sleep(1);
  return p;
end;
/

create table t (
  x int
);

insert into t 
  select rownum from dual connect by level <= 10;

commit;


第一次执行计数5行需要5秒。第二个接近0 :

SQL> set timing on
SQL>
SQL> select /*+ result_cache */count(f(x)) from t
  2  where  x <= 5;

COUNT(F(X))
-----------
          5

Elapsed: 00:00:05.52
SQL> select /*+ result_cache */count(f(x)) from t
  2  where  x <= 5;

COUNT(F(X))
-----------
          5

Elapsed: 00:00:00.47


但是,只要您向t添加另一行, Oracle就会使缓存失效。并且该查询再次占用5秒:

SQL> insert into t values (11);

1 row created.

Elapsed: 00:00:00.31
SQL> commit;

Commit complete.

Elapsed: 00:00:00.31
SQL>
SQL> select /*+ result_cache */count(f(x)) from t
  2  where  x <= 5;

COUNT(F(X))
-----------
          5

Elapsed: 00:00:05.46


所以你不能“让应用程序来管理它”,这使得它不适合对包含大量DML的表进行查询。

如果您正在寻找一种方法来拥有一个过时的数据缓存,那么MV就是最好的方法。在复杂的查询上创建MV ,并将其设置为按计划进行刷新。然后你就可以把你的应用指向MV了。

或者,您可以更改以下选项的查询/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/修改/

alter session set query_rewrite_integrity = stale_tolerated;


然后, Oracle可以自动使用查询重写到陈旧MV并从该MV返回数据:

https://www.youtube.com/watch?v=2iRadmXtMGk
https://www.youtube.com/watch?v=aSj9eDDUE-Y

FWIW ,您可以对会话中的所有语句强制进行结果缓存,其中:

alter session set result_cache_mode = force;


然后,使用no_result_cache提示对特定查询禁用它:

SQL> alter session set result_cache_mode = force;

Session altered.

Elapsed: 00:00:00.40
SQL>
SQL> select count(f(x)) from t
  2  where  x <= 5;

COUNT(F(X))
-----------
          5

Elapsed: 00:00:00.47
SQL> select /*+ no_result_cache */count(f(x)) from t
  2  where  x <= 5;

COUNT(F(X))
-----------
          5

Elapsed: 00:00:05.94

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

评论