Oracle 10g 中的 SQL 替换特性

b.r*_*oth 9 oracle oracle-10g

三四年前,我在某处的 Oracle 博客中读到 DBA 曾使用 Oracle 10g 的实时 SQL 替换特性来解决紧急事件。基本上,他以这样的方式配置 Oracle:每次收到某个查询 A 时,它都会执行另一个查询 B。没有应用程序代码更改,没有架构更改,只是一个简单的“执行查询 B 而不是 A”类型的配置。

并不是说我打算使用该功能(我可以想到一些不良后果),但出于好奇,它真的存在吗?如果是,那个功能叫什么?

Jus*_*ave 4

这听起来像DBMS_ADVANCED_REWRITE 包。Tim Hall 详细介绍了如何使用该包将应用程序的查询指向不同的表或视图

如果您只想更改查询计划而不是将查询指向不同的表,则可以使用存储大纲或 SQL 配置文件。

例如,我有FOO1 行和BAR2 行的表

SQL> select * from foo;

      COL1
----------
         1

SQL> select * from bar;

      COL1
----------
        66
        77
Run Code Online (Sandbox Code Playgroud)

我可以声明一个重写等效项,表示查询FOO应该改为命中BAR

begin
  sys.DBMS_ADVANCED_REWRITE.DECLARE_REWRITE_EQUIVALENCE(
    'Rewrite_Foo',
    'select col1 from foo',
    'select col1 from bar',
    false,
    'TEXT_MATCH' );
end;
Run Code Online (Sandbox Code Playgroud)

现在,如果我设置query_rewrite_integrity为可信,查询FOO最终会到达完全不同的表。

SQL> alter session set query_rewrite_integrity=trusted;

Session altered.

SQL> select * from foo;

      COL1
----------
        66
        77
Run Code Online (Sandbox Code Playgroud)

这可以创建一些相当有趣的查询计划,其中您正在查询的对象在计划中找不到

SQL> select * from foo;

      COL1
----------
        66
        77


Execution Plan
----------------------------------------------------------
Plan hash value: 4224476444

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |    26 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| BAR  |     2 |    26 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        584  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
Run Code Online (Sandbox Code Playgroud)