• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    FIRST_ROWS優化模式語言排序模糊匹配問題

    發布: 2009-8-04 11:37 | 作者: webmaster | 來源: 本站原創 | 查看: 207次 | 進入軟件測試論壇討論

    領測軟件測試網

    FIRST_ROWS優化模式語言排序模糊匹配問題  軟件測試工程師

    標題比較長,不過只有這樣才能把問題描述清楚。

    問題詳細描述為,在FIRST_ROWS優化模式下,將會話排序和比較方式設置為語義模式,即忽略大小寫模式,對字段進行LIKE模糊查詢,可能導致錯誤的結果。

    下面直接看問題的現象:

    SQL> CREATE TABLE T1 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));

    表已創建。

    SQL> CREATE INDEX IND_T1_NAME ON T1(NAME);

    索引已創建。

    SQL> INSERT INTO T1 SELECT ROWNUM, CHR(64 + ROWNUM) 
    2 FROM ALL_OBJECTS WHERE ROWNUM <= 26;

    已創建26行。

    SQL> COMMIT;

    提交完成。

    SQL> ALTER SESSION SET NLS_COMP = LINGUISTIC;

    會話已更改。

    SQL> ALTER SESSION SET NLS_SORT = BINARY_CI;

    會話已更改。

    SQL> SELECT * FROM T1 WHERE NAME LIKE ’a%’;

    ID NAME
    ---------- ------------------------------
    1 A

    SQL> SELECT /*+ FIRST_ROWS */ * FROM T1 WHERE NAME LIKE ’a%’;

    未選定行

    只要修改上面提到的關鍵點中的任意一個,就不會產生這個錯誤的現象:

    SQL> SELECT /*+ ALL_ROWS */ * FROM T1 WHERE NAME LIKE ’a%’;

    ID NAME
    ---------- ------------------------------
    1 A

    SQL> SELECT /*+ FIRST_ROWS */ * FROM T1 WHERE NAME = ’a’;

    ID NAME
    ---------- ------------------------------
    1 A

    SQL> ALTER SESSION SET NLS_SORT = BINARY;

    會話已更改。

    SQL> ALTER SESSION SET NLS_COMP = BINARY;

    會話已更改。

    SQL> SELECT /*+ FIRST_ROWS */ * FROM T1 WHERE NAME LIKE ’A%’;

    ID NAME
    ---------- ------------------------------
    1 A

    SQL> ALTER SESSION SET NLS_COMP = LINGUISTIC;

    會話已更改。

    SQL> ALTER SESSION SET NLS_SORT = BINARY_CI;

    會話已更改。

    SQL> SELECT /*+ FIRST_ROWS */ * FROM T1 WHERE NAME LIKE ’A%’;

    ID NAME
    ---------- ------------------------------
    1 A

    SQL> SELECT /*+ FIRST_ROWS */ * FROM T1 WHERE NAME LIKE ’a’;

    未選定行

    通過上面的幾個查詢可以看到,問題和FIRST_ROWS,LIKE操作以及基于語義的排序直接相關,下面看看Oracle在異常情況下采用了何種執行計劃:

    SQL> SET AUTOT ON EXP
    SQL> SELECT /*+ FIRST_ROWS */ * FROM T1 WHERE NAME LIKE ’a’;

    未選定行

    執行計劃
    ----------------------------------------------------------
    Plan hash value: 3350237141

    -------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    -------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 30 | 35 (0)| 00:00:01 |
    |* 1 | VIEW | index$_join$_001 | 1 | 30 | 35 (0)| 00:00:01 |
    |* 2 | HASH JOIN | | | | | |
    |* 3 | INDEX RANGE SCAN | IND_T1_NAME | 1 | 30 | 3 (34)| 00:00:01 | [Page]
    | 4 | INDEX FAST FULL SCAN| SYS_C006622 | 1 | 30 | 33 (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter(\"NAME\" LIKE ’a’)
    2 - access(ROWID=ROWID)
    3 - access(\"NAME\" LIKE ’a’)

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

    由于索引中并不包含語義查詢的結果,因此Oracle這里必須訪問表才能得到最終的結果,因此這個執行計劃是錯誤的:

    SQL> SELECT * FROM T1 WHERE NAME = ’a’;

    ID NAME
    ---------- ------------------------------
    1 A

    執行計劃
    ----------------------------------------------------------
    Plan hash value: 3617692013
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    --------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 30 | 3 (0)| 00:00:01 |
    |* 1 | TABLE ACCESS FULL| T1 | 1 | 30 | 3 (0)| 00:00:01 |
    --------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter(NLSSORT(\"NAME\",’nls_sort=’’BINARY_CI’’’)=HEXTORAW(’6100’)
    )

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

    SQL> SELECT /*+ INDEX(T1) */ * FROM T1 WHERE NAME = ’a’;

    ID NAME
    ---------- ------------------------------
    1 A

    執行計劃
    ----------------------------------------------------------
    Plan hash value: 159298173

    -------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    -------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 30 | 827 (1)| 00:00:10 |
    |* 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 30 | 827 (1)| 00:00:10 |
    | 2 | INDEX FULL SCAN | SYS_C006622 | 26 | | 26 (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter(NLSSORT(\"NAME\",’nls_sort=’’BINARY_CI’’’)=HEXTORAW(’6100’) )

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

    上面的兩個執行計劃已經說明了問題的關鍵,Oracle對于語義的排序無法通過索引獲取,必須要訪問表或者相應的函數索引,詳細描述可以參考文章開頭部分給出的鏈接。

    而采用了FIRST_ROWS優化模式后,當操作為LIKE時,Oracle優化器選擇了錯誤的執行計劃進行了優化,采用索引的范圍掃描代替了表,從而引發了錯誤: [Page]

    SQL> SELECT /*+ INDEX_JOIN(T1 IND_T1_NAME SYS_C006622) */ *
    2 FROM T1
    3 WHERE NAME LIKE ’a’;

    未選定行

    執行計劃
    ----------------------------------------------------------
    Plan hash value: 3350237141

    -------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    -------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 30 | 35 (0)| 00:00:01 |
    |* 1 | VIEW | index$_join$_001 | 1 | 30 | 35 (0)| 00:00:01 |
    |* 2 | HASH JOIN | | | | | |
    |* 3 | INDEX RANGE SCAN | IND_T1_NAME | 1 | 30 | 3 (34)| 00:00:01 |
    | 4 | INDEX FAST FULL SCAN| SYS_C006622 | 1 | 30 | 33 (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter(\"NAME\" LIKE ’a’)
    2 - access(ROWID=ROWID)
    3 - access(\"NAME\" LIKE ’a’)

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

    現在沒有使用FIRST_ROWS,而采用HINT也達到了相同的效果。而解決這個問題的方法就是通過HINT來避免索引范圍掃描的發生。

    SQL> ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS;

    會話已更改。

    SQL> SELECT * FROM T1 WHERE NAME LIKE ’a’;

    未選定行

    執行計劃
    ----------------------------------------------------------
    Plan hash value: 3350237141

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

    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    -------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 30 | 35 (0)| 00:00:01 |
    |* 1 | VIEW | index$_join$_001 | 1 | 30 | 35 (0)| 00:00:01 |
    |* 2 | HASH JOIN | | | | | |
    |* 3 | INDEX RANGE SCAN | IND_T1_NAME | 1 | 30 | 3 (34)| 00:00:01 |
    | 4 | INDEX FAST FULL SCAN| SYS_C006622 | 1 | 30 | 33 (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter(\"NAME\" LIKE ’a’)
    2 - access(ROWID=ROWID)
    3 - access(\"NAME\" LIKE ’a’)

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

    SQL> SELECT /*+ FULL(T1) */ * FROM T1 WHERE NAME LIKE ’a’; [Page]

    ID NAME
    ---------- ------------------------------
    1 A

    執行計劃
    ----------------------------------------------------------
    Plan hash value: 3617692013

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

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter(\"NAME\" LIKE ’a’)

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

    SQL> SELECT /*+ NO_INDEX(T1) */ * FROM T1 WHERE NAME LIKE ’a’;

    ID NAME
    ---------- ------------------------------
    1 A

    執行計劃
    ----------------------------------------------------------
    Plan hash value: 3617692013

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

    Predicate Information (identified by operation id):
    ---------------------------------------------------

    1 - filter(\"NAME\" LIKE ’a’)

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

    查詢metalink,Oracle在Doc ID: Note:5252496.8明確說明了這個bug,這個bug會在Oracle10.2.0.4和11.1.0.6中被Fixed。

     

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: First FIRST ROWS 模式 語言


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>