Chanel [K]

面朝大海,春暖花开

Archive for the ‘Feeling’ Category

How to Use DBMS_ADVANCED_REWRITE in Oracle 10g

with 4 comments

在Oracle10g之后,提供了DBMS_ADVANCED_REWRITE包,具有强大的查询重写功能,可以让我们在数据库层面实现很多微妙的调整。假设我们有一个应用,但是现在无法直接修改应用程序的编码,但是又想能够让应用程序的某些SQL产生我们想要的变化,那么就可以使用DBMS_ADVANCED_REWRITE包。

drop table t;
create table t as select object_id,object_name from dba_objects;
drop table t1;
create table t1 as select object_id,object_name from dba_objects where 1=0;
SQL> select count(*) from t;

  COUNT(*)
----------
     16636

SQL> select count(*) from t1;

  COUNT(*)
----------
         0

现在我们有表T和T1,表结构相同,但是表T中有1.6万记录,而表T1中没有记录,如果说我们的应用中有一个SQL多次地查询表T的总记录数,占用了大量的CPU和逻辑读,而这样的count记录数又是完全没有用处的,但是我们无法修改应用程序去掉这个SQL,那么我们就可以通过DBMS_ADVANCED_REWRITE包来讲查询表T的SQL转变为查询表T1,这样就大大减少了这条SQL的逻辑读。

首先DBMS_ADVANCED_REWRITE包的执行权限必须显式赋给需要的用户。

CONN sys/password AS SYSDBA

GRANT EXECUTE ON DBMS_ADVANCED_REWRITE TO kamus;

CONN kamus/password

BEGIN
  SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence (
     name             => 't_rewrite',
     source_stmt      => 'SELECT count(*) FROM t',
     destination_stmt => 'SELECT count(*) FROM t1',
     validate         => FALSE,
     rewrite_mode     => 'TEXT_MATCH');
END;
/

然后需要设置会话层面的QUERY_REWRITE_INTEGRITY参数,该参数默认值为ENFORCED,表示只有重写后的SQL输出结果跟原结果完全一样时,查询才会被真正重写,在这里需要修改为TRUSTED。

SQL> ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED;
SQL> set autot on
SQL> select count(*) from t;

  COUNT(*)
----------
         0

Execution Plan
----------------------------------------------------------
Plan hash value: 238181912

----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     1 |    13 |     2   (0)| 00:00:01 |
|   1 |  VIEW               |      |     1 |    13 |     2   (0)| 00:00:01 |
|   2 |   SORT AGGREGATE    |      |     1 |       |            |          |
|   3 |    TABLE ACCESS FULL| T1   |     1 |       |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        417  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> ALTER SESSION SET QUERY_REWRITE_INTEGRITY = ENFORCED;
SQL> select count(*) from t;

  COUNT(*)
----------
     16636

Execution Plan
----------------------------------------------------------
Plan hash value: 2966233522

-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |    22   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| T    | 16639 |    22   (0)| 00:00:01 |
-------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         69  consistent gets
          0  physical reads
          0  redo size
        420  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

可以看到在重写之后,执行计划中显示直接去查询表T1,而consistent gets也从查询表T需要的69减少为3。

可以从[USER|ALL|DBA]_REWRITE_EQUIVALENCES视图中获得查询重写的信息。

SQL> select * from user_rewrite_equivalences;

OWNER  NAME       SOURCE_STMT               DESTINATION_STMT          REWRITE_MO
------ ---------- ------------------------- ------------------------- ----------
KAMUS  T_REWRITE  SELECT count(*) FROM t    SELECT count(*) FROM t1   TEXT_MATCH

DBMS_ADVANCED_REWRITE包也有限制,不可以重写牵涉到SYS用户对象的SQL。

drop table t1;
create table t1 as select * from all_tables where 1=0;

SQL> BEGIN
  2    SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence (
  3       name             => 't_rewrite',
  4       source_stmt      => 'SELECT count(*) FROM all_tables',
  5       destination_stmt => 'SELECT count(*) FROM t1',
  6       validate         => FALSE,
  7       rewrite_mode     => 'TEXT_MATCH');
  8  END;
  9  /
BEGIN
*
ERROR at line 1:
ORA-30354: Query rewrite not allowed on SYS relations
ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 29
ORA-06512: at "SYS.DBMS_ADVANCED_REWRITE", line 185
ORA-06512: at line 2

在测试中,如果destination_stmt中包含SYS用户对象,是可以成功创建查询重写的,但是在执行SQL的时候却会报ORA-03113错误,后台出现ORA-07445错误,无法正常执行。

SQL> BEGIN
  2    SYS.DBMS_ADVANCED_REWRITE.declare_rewrite_equivalence (
  3       name             => 't_rewrite',
  4       source_stmt      => 'SELECT count(*) FROM t1',
  5       destination_stmt => 'SELECT count(*) FROM all_tables',
  6       validate         => FALSE,
  7       rewrite_mode     => 'TEXT_MATCH');
  8  END;
  9  /

PL/SQL procedure successfully completed.

SQL> select * from user_rewrite_equivalences;

OWNER  NAME       SOURCE_STMT               DESTINATION_STMT          REWRITE_MO
------ ---------- ------------------------- ------------------------- ----------
KAMUS  T_REWRITE  SELECT count(*) FROM t1   SELECT count(*) FROM all_ TEXT_MATCH
                                            tables

SQL> ALTER SESSION SET QUERY_REWRITE_INTEGRITY = TRUSTED;

Session altered.

SQL> select count(*) from t1;
select count(*) from t1
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 8360
Session ID: 135 Serial number: 22

Written by kamus

March 12th, 2010 at 2:11 pm

Posted in Feeling

Attitude is Altitude

with 3 comments

当看到画面的时候我很震惊。

每一个女孩儿都是漂亮的。
每一个男孩儿都是男子汉。

Attitude is Altitude。

Written by kamus

February 14th, 2010 at 10:30 pm

Posted in Feeling

Loving in Sanya

with 19 comments

晒几张婚纱照。必须得说影楼的摄影师是二百五,不停要求我们做出扭曲的pose,还要我们俩眼睛不往一处看,就好像不知道镜头在哪里一般。实在忍受不了蹂躏之后努力反抗,才有那么几张看上去还顺眼的,幸好佟老师小朋友底子好,哥虽然不帅也还将就看,总体来说没有丢祖国人民的脸。

如果不能看到下面的照片,请移步到咱们伟大祖国管辖内的网站中观看,猛击Yupoo

IMG_2569
新娘的单人照,裙摆最漂亮的一张。

IMG_2547

大东海的礁石上。

IMG_2638

还是大东海,看上去沙滩挺大,其实就那么一小块。波澜壮阔的电影如果看到拍摄现场,也就那样。

IMG_2664

十米长拖呢,二百五摄影师拍了个近景。

IMG_2680

出乎意料的米奇玩偶,倒是有出乎意料的喜感,色彩也是最鲜艳的。

IMG_2704

还是穿自己的休闲装舒服。气球的颜色和大海天空配合的也还不错。

IMG_2724

由于新娘子劳累,提前结束了拍摄,原本计划的夕照并没有如愿,这张有PS过,太阳的高度在那个位置,实际并不会有如此浓烈的黄昏色彩。

Written by kamus

February 6th, 2010 at 1:26 am

Posted in Feeling