三四年前,我在某处的 Oracle 博客中读到 DBA 曾使用 Oracle 10g 的实时 SQL 替换特性来解决紧急事件。基本上,他以这样的方式配置 Oracle:每次收到某个查询 A 时,它都会执行另一个查询 B。没有应用程序代码更改,没有架构更改,只是一个简单的“执行查询 B 而不是 A”类型的配置。
并不是说我打算使用该功能(我可以想到一些不良后果),但出于好奇,它真的存在吗?如果是,那个功能叫什么?
这听起来像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)
| 归档时间: |
|
| 查看次数: |
524 次 |
| 最近记录: |