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

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

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

    Decode360's Blog

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

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
      397 隨筆 :: 33 文章 :: 29 評(píng)論 :: 0 Trackbacks
    Update時(shí)不走索引的問(wèn)題
    ?
    ??? 今天工作上遇到了一個(gè)問(wèn)題,一個(gè)好幾萬(wàn)數(shù)據(jù)的大表update數(shù)據(jù)時(shí)不走索引,時(shí)間長(zhǎng)到無(wú)法忍受。建一個(gè)環(huán)境模擬一下:
    ?
    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;
    ?
    ?
    ??? 用來(lái)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)

    ?
    ??? 上網(wǎng)看了一下,發(fā)現(xiàn)有人遇到跟我一樣的問(wèn)題,連原因也一樣,具體網(wǎng)址: http://space.itpub.net/16179598/viewspace-539595
    ?
    ??? 在t1_a表的a字段外加上to_char函數(shù)后,使用索引:
    ?
    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自動(dòng)進(jìn)行類型轉(zhuǎn)換之后就不再走索引了。
    ?
    ?
    drop table t1_a;
    drop table t1_b;
    set autotrace off;?
    ?
    ?
    ?
    因?yàn)閷?shí)際中是由于varchar2與nvarchar2類型不匹配造成,所以轉(zhuǎn)一篇NVARCHAR2類型介紹的帖子
    ***************************************************************************************************************
    ?
    輸入NVARCHRA2類型字符串
    ===========================================================

    今天看到論壇的一個(gè)帖子,是關(guān)于NVARCHAR2字符串的。解答之后,順便問(wèn)了問(wèn)同事,發(fā)現(xiàn)居然大家都不知道這個(gè)語(yǔ)法。所以這里簡(jiǎn)單描述一下。


    其實(shí)語(yǔ)法非常檢查,要指定一個(gè)國(guó)家字符集的字符串NCHARNVARCHAR2,只需要在字符串前面加上一個(gè)N就可以了。

    舉個(gè)例子:

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

    表已創(chuàng)建。

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

    已創(chuàng)建 1 行。

    SQL> DROP TABLE T_NVARCHAR2 PURGE;

    表已刪除。

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

    表已創(chuàng)建。

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

    已創(chuàng)建 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

    如果對(duì)于VARCHAR2類型的表指定NVARCHAR2類型的查詢,Oracle會(huì)自動(dòng)進(jìn)行隱式類型轉(zhuǎn)換。

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

    表已創(chuàng)建。

    SQL> CREATE INDEX IND_T_NAME ON T(NAME);

    索引已創(chuàng)建。

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

    已創(chuàng)建54020行。

    SQL> COMMIT;

    提交完成。

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

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

    執(zhí)行計(jì)劃
    ----------------------------------------------------------
    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

    執(zhí)行計(jì)劃
    ----------------------------------------------------------
    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

    這個(gè)隱式轉(zhuǎn)換過(guò)程會(huì)將列字段的VARCHAR2類型轉(zhuǎn)換為NVARCHAR2類型,導(dǎo)致索引無(wú)法使用。如果想要這種情況下仍然可以使用索引,需要建立一個(gè)函數(shù)索引:

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

    索引已創(chuàng)建。

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

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

    執(zhí)行計(jì)劃
    ----------------------------------------------------------
    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 發(fā)表于:2009.01.07 22:15 ::分類: ( ORACLE ) ::閱讀:(344次) :: 評(píng)論 (1)
    ***************************************************************************************************************
    ?
    ?
    posted on 2009-01-26 18:16 decode360 閱讀(593) 評(píng)論(0)  編輯  收藏 所屬分類: 05.SQL
    主站蜘蛛池模板: 相泽南亚洲一区二区在线播放| 成全视频免费高清| 亚洲a∨无码一区二区| 亚洲男人都懂得羞羞网站| 日韩亚洲精品福利| 无码一区二区三区免费视频| 中国一级毛片视频免费看| 亚洲成熟丰满熟妇高潮XXXXX| 亚洲av永久无码精品网站| 日韩亚洲国产二区| 免费视频淫片aa毛片| 16女性下面无遮挡免费| 久久性生大片免费观看性| 人人狠狠综合久久亚洲| 伊人久久五月丁香综合中文亚洲| 无码专区—VA亚洲V天堂| 久久精品国产亚洲一区二区三区| 国产一区在线观看免费| 欧美a级成人网站免费| 99re在线精品视频免费| 精品国产污污免费网站| 99久久成人国产精品免费| 特色特黄a毛片高清免费观看| 亚洲国产成人AV网站| 亚洲av中文无码乱人伦在线观看| 亚洲成在人线电影天堂色| 日本亚洲视频在线 | 岛国岛国免费V片在线观看| 91嫩草亚洲精品| 亚洲国产成人一区二区精品区 | 污视频在线免费观看| 亚洲一级片在线观看| 亚洲日韩精品一区二区三区无码 | 国产美女无遮挡免费视频| 久久久久久曰本AV免费免费| 拍拍拍无挡免费视频网站| jizz免费观看视频| 边摸边吃奶边做爽免费视频网站| 亚洲私人无码综合久久网| 亚洲国产日韩在线成人蜜芽 | 男男黄GAY片免费网站WWW|