• 當前位置:首頁 > IT技術 > 移動平臺 > 正文

    Oracle insert /*+ APPEND */原理解析
    2021-08-09 18:50:53

    關于insert /*+ append */我們需要注意以下三點: a、非歸檔模式下,只需append就能大量減少redo的產生;歸檔模式下,只有append+nologging才能大量減少redo。 b、insert /*+ append */時會對表加鎖(排它鎖),會阻塞表上的除了select以外所有DML語句;傳統

    關于insert /*+ append */我們需要注意以下三點:

    a、非歸檔模式下,只需append就能大量減少redo的產生;歸檔模式下,只有append+nologging才能大量減少redo。
    b、insert /*+ append */?時會對表加鎖(排它鎖),會阻塞表上的除了select以外所有DML語句;傳統的DML在TM enqueue上使用模式3(row exclusive),其允許其他DML在相同的模式上獲得TM enqueue。但是直接路徑加載在TM enqueue使用模式6(exclusive),這使其他DML在直接路徑加載期間將被阻塞。
    c、insert /*+ append */?直接路徑加載,速度比常規加載方式快。因為是從HWM的位置開始插入,也許會造成空間浪費。

    1.環境介紹

    數據庫版本:

    1

    2

    3

    4

    5

    6

    7

    8

    SQL>?select?*?from?v$version;

    BANNER

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

    Oracle?Database?11g Enterprise Edition Release 11.2.0.1.0 - Production

    PL/SQL Release 11.2.0.1.0 - Production

    CORE??? 11.2.0.1.0????? Production

    TNS?for?Linux: Version 11.2.0.1.0 - Production

    NLSRTL Version 11.2.0.1.0 - Production

    網上說測試時不要使用auto trace來查看redo size,這個值是有偏差的.建議建立一個視圖:

    1

    2

    3

    4

    5

    6

    SQL>?create?or?replace?view?redo_size?as

    select?value

    from?v$mystat, v$statname

    where?v$mystat.statistic# = v$statname.statistic#

    and?v$statname.name?=?'redo size';

    -- 視圖已創建。

    2.示例演示:

    2.1 非歸檔模式

    1

    2

    3

    4

    5

    6

    SQL> archive log list

    數據庫日志模式???????????? 非存檔模式

    自動存檔???????????? 禁用

    存檔終點??????????? USE_DB_RECOVERY_FILE_DEST

    最早的聯機日志序列???? 95

    當前日志序列?????????? 97

    2.1.1 nologging表

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    SQL>?create?table?test1 nologging?as?select?*?from?dba_objects?where?1=0;

    表已創建。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??25714940

    ??

    SQL>?insert?into?test1?select?*?from?dba_objects;

    已創建72753行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??34216916

    ??

    SQL>?insert?/*+ APPEND */??into?test1?select?*?from?dba_objects;

    已創建72753行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??34231736

    ??

    SQL>?select?(34231736-34216916) redo_append , (34216916-25714940) redo_normalfrom?dual;

    REDO_APPEND REDO_NORMAL

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

    ??????14820???? 8501976

    2.1.2 logging表:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    SQL>?create?table?test2?as?select?*?from?dba_objects?where?1=0;

    ??

    表已創建。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??34273348

    ??

    SQL>?insert?into?test2?select?*?from?dba_objects;

    ??

    已創建72754行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??42775336

    ??

    SQL>?insert?/*+ APPEND */??into?test2?select?*?from?dba_objects;

    已創建72754行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??42790156

    ??

    SQL>?select?(42790156-42775336) redo_append , (42775336-34273348) redo_normalfrom?dual;

    REDO_APPEND REDO_NORMAL

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

    ??????14820???? 8501988

    2.2歸檔模式下:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    SQL> shutdown immediate

    數據庫已經關閉。

    已經卸載數據庫。

    ORACLE例程已經關閉。

    SQL> startup mount

    ORACLE例程已經啟動。

    ??

    Total System?Global?Area? 477073408 bytes

    Fixed?Size??????????????????1337324 bytes

    Variable?Size?????????????293603348 bytes

    Database?Buffers????????? 176160768 bytes

    Redo Buffers??????????????? 5971968 bytes

    數據庫裝載完畢。

    SQL>?alter?database?archivelog;

    數據庫已更改。

    ??

    SQL>?alter?database?open;

    數據庫已更改。

    ??

    SQL> archive log list

    數據庫日志模式??????????? 存檔模式

    自動存檔???????????? 啟用

    存檔終點??????????? USE_DB_RECOVERY_FILE_DEST

    最早的聯機日志序列???? 95

    下一個存檔日志序列?? 97

    當前日志序列?????????? 97

    2.2.1 nologging表

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    SQL>?select?*?from?redo_size;

    ????VALUE

    ----------

    ?????17936

    ??

    SQL>?insert?into?test1?select?*?from?dba_objects;

    已創建72754行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ???8490972

    ??

    SQL>?insert?/*+ APPEND */??into?test1?select?*?from?dba_objects;

    已創建72754行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ???8506164

    ??

    SQL>?select?(8506164-8490972) redo_append , (8490972-17936) redo_normal?fromdual;

    REDO_APPEND REDO_NORMAL

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

    ??????15192???? 8473036

    2.2.2 logging表

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ???8506780

    ??

    SQL>?insert?into?test2?select?*?from?dba_objects;

    已創建72754行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??16979516

    ??

    SQL>?insert?/*+ APPEND */??into?test2?select?*?from?dba_objects;

    已創建72754行。

    ??

    SQL>?select?*?from?redo_size;

    ?????VALUE

    ----------

    ??25518172

    ??

    SQL>?select?(25518172-16979516) redo_append , (16979516-8506780) redo_normalfrom?dual;

    REDO_APPEND REDO_NORMAL

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

    ????8538656???? 8472736

    在歸檔模式下,對于常規表的insert append產生和insert同樣的redo
    此時的insert append實際上并不會有性能提高.
    但是此時的append是生效了的。

    3.insert /*+ append */會阻塞除select以外的DML語句,direct-path insert操作是單獨一個事務。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    SQL>?select?count(*)?from?test2;

    ??COUNT(*)

    ----------

    ????291016

    ??

    SQL>?insert?into?test2?select?*?from?dba_objects;

    已創建72754行。

    ??

    SQL>?select?count(*)?from?test2;

    ??COUNT(*)

    ----------

    ????363770

    ??

    SQL>?insert?/*+ APPEND */?into?test2?select?*?from?dba_objects;

    已創建72754行

    ??

    同一個session下:

    ??

    SQL>?select?count(*)?from?test2;

    select?count(*)?from?test2

    *

    第 1 行出現錯誤:

    ORA-12838: 無法在并行模式下修改之后讀/修改對象

    ??

    SQL>?commit;

    提交完成。

    ??

    SQL>?select?count(*)?from?test2;

    ??COUNT(*)

    ----------

    ????436524

    ??

    SQL>?insert?/*+ APPEND */?into?test2?select?*?from?dba_objects;

    已創建72754行。

    ??

    SQL> shutdown immediate

    ORA-01097: 無法在事務處理過程中關閉 - 請首先提交或回退

    ??

    SQL>?select??*?from?v$mystat?where?rownum<2;

    ??

    ???????SID STATISTIC#????? VALUE

    ??

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

    ??

    ???????224????????? 0????????? 1

    ??

    SQL>?select?KADDR,TYPE,LMODE?from?v$lock?where?sid=224;

    ??

    KADDR??????????? TY????? LMODE

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

    0000000071BAE180 TM????????? 6

    0000000070CB11B8 TX????????? 6

    另外開啟一個會話,就會發現只能select,其他DML全部阻塞。

    ?

    本文摘自 :https://blog.51cto.com/u

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码