<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 :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
      302 隨筆 :: 26 文章 :: 82 評論 :: 0 Trackbacks
    ??? 今天工作上遇到了一個問題,一個好幾萬數據的大表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)
    ?
    ?




    -The End-

    posted on 2009-01-26 18:16 decode360-3 閱讀(905) 評論(0)  編輯  收藏 所屬分類: SQL Dev
    主站蜘蛛池模板: 看免费毛片天天看| 无人视频在线观看免费播放影院| 日本免费网站视频www区| 羞羞视频免费网站日本| 99亚洲精品卡2卡三卡4卡2卡| 亚洲最大在线观看| 亚洲精品在线免费观看视频| 亚洲VA中文字幕不卡无码| 亚洲综合国产一区二区三区 | 国产精品色午夜视频免费看| 国色精品卡一卡2卡3卡4卡免费 | 亚洲永久无码3D动漫一区| 四虎永久免费影院| 亚洲日本一区二区一本一道| 亚洲一区二区精品视频| 免费又黄又爽又猛的毛片| 亚洲精品tv久久久久| 中文字幕精品无码亚洲字| 亚洲熟妇中文字幕五十中出| 亚洲午夜久久久久久噜噜噜| 亚洲AV日韩AV天堂久久| 亚洲高清免费在线观看| 中文字幕亚洲综合久久综合| 鲁死你资源站亚洲av| 皇色在线免费视频| 最近新韩国日本免费观看 | 亚洲一区二区三区在线网站| 亚洲国产精品无码久久九九大片 | 久久99国产亚洲高清观看首页| 亚洲欧洲一区二区| 黄色一级免费网站| 免费黄色网址网站| 不卡精品国产_亚洲人成在线| 亚洲人成黄网在线观看| 好吊色永久免费视频大全| 成人午夜大片免费7777| 亚洲欧洲第一a在线观看| 成人a毛片免费视频观看| 永久免费毛片在线播放| 亚洲精品美女久久777777| 亚洲一区二区三区国产精华液|