<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Decode360's Blog

    業精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
      397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
    Update時不走索引的問題
    ?
    ??? 今天工作上遇到了一個問題,一個好幾萬數據的大表update數據時不走索引,時間長到無法忍受。建一個環境模擬一下:
    ?
    create table t1_a(a int,b varchar2(100),c varchar2(100));
    create table t1_b(a varchar2(2),bb varchar2(100),cc varchar2(100));
    ?
    create index t1_a_idx on t1_a(a);
    create index t1_b_idx on t1_b(a);
    ?
    insert into t1_a values(1,'b1','c1');
    insert into t1_a values(2,'b2','c2');
    insert into t1_a values(3,'b3','c3');
    insert into t1_a values(4,'b4','c4');
    insert into t1_a values(5,'b5','c5');
    insert into t1_b values('1','bb1','cc1');
    insert into t1_b values('2','bb2','cc2');
    insert into t1_b values('3','bb3','cc3');
    insert into t1_b values('4','bb4','cc4');
    insert into t1_b values('5','bb5','cc5');
    ?
    commit;
    ?
    ?
    ??? 用來update的SQL是這樣的:
    ?
    update t1_a set (b,c) = (select bb,cc from t1_b where a=t1_a.a);
    ?
    Execution Plan
    ----------------------------------------------------------
    ?? 0????? UPDATE STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=5 Bytes=585)
    ?? 1??? 0?? UPDATE OF 'T1_A'
    ?? 2??? 1???? TABLE ACCESS (FULL) OF 'T1_A' (TABLE) (Cost=3 Card=5 Bytes=585)
    ?? 3??? 1???? TABLE ACCESS (FULL) OF 'T1_B' (TABLE) (Cost=3 Card=1 Bytes=107)

    ?
    ??? 上網看了一下,發現有人遇到跟我一樣的問題,連原因也一樣,具體網址: http://space.itpub.net/16179598/viewspace-539595
    ?
    ??? 在t1_a表的a字段外加上to_char函數后,使用索引:
    ?
    update t1_a set (b,c) = (select bb,cc from t1_b where a=to_char(t1_a.a));
    ?
    Execution Plan
    ----------------------------------------------------------
    ?? 0????? UPDATE STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=5 Bytes=585)
    ?? 1??? 0?? UPDATE OF 'T1_A'
    ?? 2??? 1???? TABLE ACCESS (FULL) OF 'T1_A' (TABLE) (Cost=3 Card=5 Bytes=585)
    ?? 3??? 1???? TABLE ACCESS (BY INDEX ROWID) OF 'T1_B' (TABLE) (Cost=2 Card=1 Bytes=107)
    ?? 4??? 3?????? INDEX (RANGE SCAN) OF 'T1_B_IDX' (INDEX) (Cost=1 Card=1)
    ?
    ??? 這樣速度就快很多了,主要原因是oracle自動進行類型轉換之后就不再走索引了。
    ?
    ?
    drop table t1_a;
    drop table t1_b;
    set autotrace off;?
    ?
    ?
    ?
    因為實際中是由于varchar2與nvarchar2類型不匹配造成,所以轉一篇NVARCHAR2類型介紹的帖子
    ***************************************************************************************************************
    ?
    輸入NVARCHRA2類型字符串
    ===========================================================

    今天看到論壇的一個帖子,是關于NVARCHAR2字符串的。解答之后,順便問了問同事,發現居然大家都不知道這個語法。所以這里簡單描述一下。


    其實語法非常檢查,要指定一個國家字符集的字符串NCHARNVARCHAR2,只需要在字符串前面加上一個N就可以了。

    舉個例子:

    SQL> CREATE TABLE T_NVARCHAR2 (ID NUMBER, NAME NVARCHAR2(30));

    表已創建。

    SQL> INSERT INTO T_NVARCHAR2 VALUES (1, N'ABC');

    已創建 1 行。

    SQL> DROP TABLE T_NVARCHAR2 PURGE;

    表已刪除。

    SQL> CREATE TABLE T_NVARCHAR2 (ID NUMBER, NAME NVARCHAR2(30));

    表已創建。

    SQL> INSERT INTO T_NVARCHAR2 VALUES (1, N'ABC');

    已創建 1 行。

    SQL> COMMIT;

    提交完成。

    SQL> SELECT DUMP(NAME, 16) FROM T_NVARCHAR2;

    DUMP(NAME,16)
    ---------------------------------------------------------------------------------------
    Typ=1 Len=6: 0,41,0,42,0,43

    SQL> SELECT DUMP('ABC', 16) VAR, DUMP(N'ABC', 16) NVAR FROM DUAL;

    VAR NVAR
    -------------------------------------------- ----------------------------------------
    Typ=96 Len=3: 41,42,43 Typ=96 Len=6: 0,41,0,42,0,43

    如果對于VARCHAR2類型的表指定NVARCHAR2類型的查詢,Oracle會自動進行隱式類型轉換。

    SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));

    表已創建。

    SQL> CREATE INDEX IND_T_NAME ON T(NAME);

    索引已創建。

    SQL> INSERT INTO T SELECT ROWNUM, OBJECT_NAME FROM ALL_OBJECTS;

    已創建54020行。

    SQL> COMMIT;

    提交完成。

    SQL> SET AUTOT ON EXP
    SQL> SELECT * FROM T WHERE NAME = 'T';

    ID NAME
    ---------- ------------------------------
    53170 T

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

    ------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 1 | 30 | 2 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 30 | 2 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | IND_T_NAME | 1 | | 1 (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------

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

    2 - access("NAME"='T')

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

    SQL> SELECT * FROM T WHERE NAME = N'T';

    ID NAME
    ---------- ------------------------------
    53170 T

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

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

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

    1 - filter(SYS_OP_C2C("NAME")=U'T')

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

    這個隱式轉換過程會將列字段的VARCHAR2類型轉換為NVARCHAR2類型,導致索引無法使用。如果想要這種情況下仍然可以使用索引,需要建立一個函數索引:

    SQL> CREATE INDEX IND_T_NNAME ON T(TO_NCHAR(NAME));

    索引已創建。

    SQL> SELECT * FROM T WHERE NAME = N'T';

    ID NAME
    ---------- ------------------------------
    53170 T

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

    -------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    -------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 567 | 60669 | 48 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| T | 567 | 60669 | 48 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | IND_T_NNAME | 227 | | 1 (0)| 00:00:01 |
    -------------------------------------------------------------------------------------------

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

    2 - access(SYS_OP_C2C("NAME")=U'T')

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

    yangtingkun 發表于:2009.01.07 22:15 ::分類: ( ORACLE ) ::閱讀:(344次) :: 評論 (1)
    ***************************************************************************************************************
    ?
    ?
    posted on 2009-01-26 18:16 decode360 閱讀(594) 評論(0)  編輯  收藏 所屬分類: 05.SQL
    主站蜘蛛池模板: 无码国产精品一区二区免费I6| 最近免费中文字幕MV在线视频3 | 国产高清视频免费在线观看 | 亚洲男人第一av网站| 中文在线免费观看| 国产亚洲视频在线播放| 久久嫩草影院免费看夜色| 亚洲精品乱码久久久久久中文字幕| 久久99久久成人免费播放| 亚洲精品V欧洲精品V日韩精品| 9久热这里只有精品免费| 亚洲一区AV无码少妇电影☆| 99热在线日韩精品免费| 亚洲AV人无码综合在线观看| 曰批视频免费40分钟试看天天 | 久久久久亚洲AV片无码| 久久免费看少妇高潮V片特黄| 亚洲第一福利网站| 野花高清在线观看免费完整版中文| 亚洲色成人四虎在线观看| 国产乱弄免费视频| 一个人看的www免费视频在线观看| 无码乱人伦一区二区亚洲| 国产人在线成免费视频| 久久久久久亚洲精品无码| 国产精品亚洲αv天堂无码| 免费成人高清在线视频| 亚洲国产视频久久| 亚洲国产成人久久一区WWW| 国内永久免费crm系统z在线| 亚洲精品国产第1页| 在线永久免费观看黄网站| a级日本高清免费看| 亚洲1234区乱码| 亚洲国产高清精品线久久| 免费无码一区二区三区| 亚洲av日韩av永久在线观看| 国产亚洲色婷婷久久99精品 | 免费看国产曰批40分钟| 久久99精品国产免费观看| 亚洲aⅴ无码专区在线观看|