QUERY_REWRITE_INTEGRITY

QUERY_REWRITE_INTEGRITY

Property Description
Parameter type String
Syntax QUERY_REWRITE_INTEGRITY = { enforced | trusted | stale_tolerated }
Default value enforced
Modifiable ALTER SESSIONALTER SYSTEM
Real Application Clusters Multiple instances can have different values.

QUERY_REWRITE_INTEGRITY determines the degree to which Oracle must enforce query rewriting. At the safest level, Oracle does not use query rewrite transformations that rely on unenforced relationships.

Values:

  • enforced

    Oracle enforces and guarantees consistency and integrity.

  • trusted

    Oracle allows rewrites using relationships that have been declared, but that are not enforced by Oracle.

  • stale_tolerated

    Oracle allows rewrites using unenforced relationships. Materialized views are eligible for rewrite even if they are known to be inconsistent with the underlying detail data.



    實驗:
      TOM書上的例子,我自己做一些實驗 大家一起理解
      
    首先我設置 QUERY_REWRITE_INTEGRITY = ENFORCED




    TYGER@ORCL>create table emp as select * from scott.emp;


    Table created.


    TYGER@ORCL>create table dept as select * from scott.dept;


    Table created.




    TYGER@ORCL>show parameter query


    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      enforced
    TYGER@ORCL>
    TYGER@ORCL>create materialized view emp_dept
      2  build immediate
      3  refresh on demand
      4  enable query rewrite
      5  as 
      6     select dept.deptno,dept.dname,count(*)
      7     from emp,dept
      8     where emp.deptno=dept.deptno
      9     group by dept.deptno,dept.dname
     10  /


    Materialized view created.


    TYGER@ORCL>show parameter optimizer


    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    optimizer_dynamic_sampling           integer     2
    optimizer_features_enable            string      10.2.0.1
    optimizer_index_caching              integer     0
    optimizer_index_cost_adj             integer     100
    optimizer_mode                       string      ALL_ROWS
    optimizer_secure_view_merging        boolean     TRUE
    TYGER@ORCL>set autot traceonly explain
    TYGER@ORCL>select count(*) from emp;


      COUNT(*)
    ----------
            14




    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2083865914


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


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




     
    TYGER@ORCL>desc emp
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     EMPNO                                              NUMBER(4)
     ENAME                                              VARCHAR2(10)
     JOB                                                VARCHAR2(9)
     MGR                                                NUMBER(4)
     HIREDATE                                           DATE
     SAL                                                NUMBER(7,2)
     COMM                                               NUMBER(7,2)
     DEPTNO                                             NUMBER(2)


    TYGER@ORCL>desc dept
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     DEPTNO                                             NUMBER(2)
     DNAME                                              VARCHAR2(14)
     LOC                                                VARCHAR2(13)


    總結: 之所以發生這種情況是由於知道 DEPTNO 是 DEPT 表的主鍵,DEPTNO 在表 EMP 中應該是 NOT NULL 的,EMP 表的 DEPTNO 應該是基於 DEPT 表 DEPTNO 列的外鍵,但是由於我們的表沒有這個外鍵約束存在,而 query_rewrite_integrity 又設置爲 enforced ,優化器爲了得到完整可靠的數據不得不查詢基表而得出最終結果。


    假如我們加上上面的規則,再看查詢結果:


    TYGER@ORCL>alter table dept add constraint dept_pk primary key(deptno);


    Table altered.


    TYGER@ORCL>desc dept
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     DEPTNO                                    NOT NULL NUMBER(2)
     DNAME                                              VARCHAR2(14)
     LOC                                                VARCHAR2(13)


     TYGER@ORCL>alter table emp
      2  add constraint emp_fk_dept
      3  foreign key(deptno) references dept(deptno);


    Table altered.


    TYGER@ORCL>alter table emp modify deptno not null;


    Table altered.


    TYGER@ORCL>desc emp;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     EMPNO                                              NUMBER(4)
     ENAME                                              VARCHAR2(10)
     JOB                                                VARCHAR2(9)
     MGR                                                NUMBER(4)
     HIREDATE                                           DATE
     SAL                                                NUMBER(7,2)
     COMM                                               NUMBER(7,2)
     DEPTNO                                    NOT NULL NUMBER(2)


     TYGER@ORCL>set autot traceonly explain
    TYGER@ORCL>select count(*) from emp;


      COUNT(*)
    ----------
            14




    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 155013515


    --------------------------------------------------------------------------------
    ----------


    | Id  | Operation                     | Name     | Rows  | Bytes | Cost (%CPU)|
    Time     |


    --------------------------------------------------------------------------------
    ----------


    |   0 | SELECT STATEMENT              |          |     1 |    13 |     3   (0)|
    00:00:01 |


    |   1 |  SORT AGGREGATE               |          |     1 |    13 |            |
             |


    |   2 |   MAT_VIEW REWRITE ACCESS FULL| EMP_DEPT |     3 |    39 |     3   (0)|
    00:00:01 |


    --------------------------------------------------------------------------------
    ----------




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






    可見 當我們將完整性約束全部添加後,優化器有了足夠的信息知道這條語句通過物化視圖可以查詢重寫,而不用查詢基表,實際的執行情況也印證了這一點。




    我們在通過一個例子說明 THUSTED 的情況。我們首先將這些約束去除掉,然後添加一行新的數據


    TYGER@ORCL>alter table emp drop constraint emp_fk_dept;


    Table altered.


    TYGER@ORCL>alter table dept drop constraint dept_pk;


    Table altered.


    TYGER@ORCL>alter table emp modify deptno null;


    Table altered.


    TYGER@ORCL>desc dept 
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     DEPTNO                                             NUMBER(2)
     DNAME                                              VARCHAR2(14)
     LOC                                                VARCHAR2(13)


    TYGER@ORCL>desc emp;
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     EMPNO                                              NUMBER(4)
     ENAME                                              VARCHAR2(10)
     JOB                                                VARCHAR2(9)
     MGR                                                NUMBER(4)
     HIREDATE                                           DATE
     SAL                                                NUMBER(7,2)
     COMM                                               NUMBER(7,2)
     DEPTNO                                             NUMBER(2)


     
     // 插入一條違反實際約束行
    TYGER@ORCL>insert into emp(empno,deptno) values(1,1);


    1 row created.


    TYGER@ORCL>exec dbms_mview.refresh('EMP_DEPT');


    PL/SQL procedure successfully completed.


    TYGER@ORCL>alter materialized view emp_dept consider fresh;
    alter materialized view emp_dept consider fresh
            *
    ERROR at line 1:
    ORA-30374: materialized view is already fresh


     
     // 創建一個 novalidate 的約束
    TYGER@ORCL>alter table dept
      2  add constraint dept_pk primary key(deptno)
      3  rely enable novalidate
      4  /


    Table altered.


    TYGER@ORCL>alter table emp
      2  add constraint emp_fk_dept
      3  foreign key(deptno) references dept(deptno)
      4  rely enable novalidate
      5  /


    Table altered.


    TYGER@ORCL>alter table emp modify deptno not null novalidate;


    Table altered.


    回到原來的查詢,假如 query_rewrite_integrity = enforced 的話,那麼我們知道由於上述約束實際上是違反真實數據約束的,因此優化器將不會利用物化視圖查詢重寫。


    TYGER@ORCL>show parameter query


    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      enforced
    TYGER@ORCL>
    TYGER@ORCL>set autot traceonly explain
    TYGER@ORCL>select count(*) from emp;


      COUNT(*)
    ----------
            16




    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2083865914


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


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




    而如果設置 query_rewrite_integrity = trusted 的話,那麼優化器因爲有了我們上述那個 novalidate約束的誤導,它並不真實檢驗數據的完整性,因此還將會利用物化視圖查詢重寫,儘管這樣得出的結果是錯誤的。只要我們讓優化器知道有完整性約束的存在,不管約束嚴格與否,優化器只要爲了這個信息就會儘可能地利用物化視圖查詢重寫。


    TYGER@ORCL>alter session set query_rewrite_integrity=trusted;


    Session altered.


    TYGER@ORCL>select count(*) from emp;


      COUNT(*)
    ----------
            14




    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 155013515


    --------------------------------------------------------------------------------
    ----------


    | Id  | Operation                     | Name     | Rows  | Bytes | Cost (%CPU)|
    Time     |


    --------------------------------------------------------------------------------
    ----------


    |   0 | SELECT STATEMENT              |          |     1 |    13 |     3   (0)|
    00:00:01 |


    |   1 |  SORT AGGREGATE               |          |     1 |    13 |            |
             |


    |   2 |   MAT_VIEW REWRITE ACCESS FULL| EMP_DEPT |     3 |    39 |     3   (0)|
    00:00:01 |


    --------------------------------------------------------------------------------
    ----------




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


    而 stale_tolerated 就簡單了:   


    /* 結果 我自己做實驗卻沒有得到的想要的結果: */


    TYGER@ORCL>show parameter query


    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      enforced


    // session 級別修改參數


    TYGER@ORCL>alter session set query_rewrite_integrity=stale_tolerated;


    Session altered.


    TYGER@ORCL>show parameter query


    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      STALE_TOLERATED
    TYGER@ORCL>set autot traceonly explain;
    TYGER@ORCL>select count(*) from emp;


    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2083865914


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


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


       // system 級別修改參數  仍然如此
       
    TYGER@ORCL>alter system set query_rewrite_integrity=stale_tolerated;


    System altered.


    TYGER@ORCL>set autot traceonly explain;
    TYGER@ORCL>select count(*) from emp;


    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2083865914


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


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


     // 重新啓動數據庫     結果依舊
     
    TYGER@ORCL>conn / as sysdba
    Connected.
    SYS@ORCL>shutdown immediate
    Database closed.
    Database dismounted.
    ORACLE instance shut down.
    SYS@ORCL>startup
    ORACLE instance started.


    Total System Global Area  285212672 bytes
    Fixed Size                  1218992 bytes
    Variable Size              71304784 bytes
    Database Buffers          209715200 bytes
    Redo Buffers                2973696 bytes
    Database mounted.
    Database opened.
    SYS@ORCL>conn tyger/tyger
    Connected.
    TYGER@ORCL>show parameter query


    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    query_rewrite_enabled                string      TRUE
    query_rewrite_integrity              string      STALE_TOLERATED
    TYGER@ORCL>set autot traceonly explain
    TYGER@ORCL>select count(*) from emp;


    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2083865914


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


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




    雖然結果有點不是很滿意,但是看完後基本可以瞭解  query_rewrite_integrity 這個參數了吧 




    遺留問題:356 行 stale_tolerated 參數設置,    如果看出錯誤的步驟 歡迎指正。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章