你的位置:首页 > 数据库

[数据库]【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较


【知识点整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较

1  BLOG文档结构图

wps98E0.tmp 

 

2  前言部分

2.1  导读和注意事项

各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~:

① 系统和会话级别的REDO和UNDO量的查询

② NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较(重点)

  Tips:

① 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和微信公众号(xiaomaimiaolhr)有同步更新。

② 文章中用到的所有代码,相关软件,相关资料请前往小麦苗的云盘下载(http://blog.itpub.net/26736162/viewspace-1624453/)。

③ 若网页文章代码格式有错乱,推荐使用360浏览器,也可以下载pdf格式的文档来查看,pdf文档下载地址:http://blog.itpub.net/26736162/viewspace-1624453/,另外itpub格式显示有问题,也可以去博客园地址阅读。

④ 本篇BLOG中命令的输出部分需要特别关注的地方我都用灰色背景和粉红色字体来表示,比如下边的例子中,thread 1的最大归档日志号为33,thread 2的最大归档日志号为43是需要特别关注的地方;而命令一般使用黄色背景和红色字体标注;对代码或代码输出部分的注释一般采用蓝色字体表示。

  List of Archived Logs in backup set 11

  Thrd Seq     Low SCN    Low Time            Next SCN   Next Time

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

  1    32      1621589    2015-05-29 11:09:52 1625242    2015-05-29 11:15:48

  1    33      1625242    2015-05-29 11:15:48 1625293    2015-05-29 11:15:58

  2    42      1613951    2015-05-29 10:41:18 1625245    2015-05-29 11:15:49

  2    43      1625245    2015-05-29 11:15:49 1625253    2015-05-29 11:15:53

[ZHLHRDB1:root]:/>lsvg -o

T_XLHRD_APP1_vg

rootvg

[ZHLHRDB1:root]:/>

00:27:22 SQL> alter tablespace idxtbs read write;

====》2097152*512/1024/1024/1024=1G

 

本文如有错误或不完善的地方请大家多多指正,ITPUB留言或QQ皆可,您的批评指正是我写作的最大动力。

3  REDOUNDO生成量的查询

说明:反映UNDO、REDO占用量的统计指标是:

UNDO:undo change vector size

REDO:redo size

 

1、查看全局数据库REDO生成量,可以通过V$SYSSTAT视图查询

SELECT NAME,

       VALUE

FROM   V$SYSSTAT

WHERE  NAME = 'redo size';

     wps98E1.tmp

2、查看当前会话的REDO生成量,可以通过V$MYSTAT或V$SESSTAT视图查询

create or replace view redo_size as 

SELECT VALUE

FROM   v$mystat   my,

       v$statname  st

WHERE  my.statistic# =st.STATISTIC#

AND    st.name = 'redo size';

----下边的实验将用到这个视图

CREATE OR REPLACE VIEW VW_REDO_UNDO_LHR AS 

SELECT (SELECT NB.VALUE

          FROM V$MYSTAT NB, V$STATNAME ST

         WHERE NB.STATISTIC# = ST.STATISTIC#

           AND ST.NAME = 'redo size') REDO,

       (SELECT NB.VALUE

          FROM V$MYSTAT NB, V$STATNAME ST

         WHERE NB.STATISTIC# = ST.STATISTIC#

           AND ST.NAME = 'undo change vector size') UNDO

  FROM DUAL;

 

或:

CREATE OR REPLACE VIEW VW_REDO_UNDO_LHR AS 

SELECT (SELECT NB.VALUE

          FROM v$sesstat NB, V$STATNAME ST

         WHERE NB.STATISTIC# = ST.STATISTIC#

           AND ST.NAME = 'redo size'

 AND NB.SID=USERENV('SID')) REDO,

       (SELECT NB.VALUE

          FROM v$sesstat NB, V$STATNAME ST

         WHERE NB.STATISTIC# = ST.STATISTIC#

           AND ST.NAME = 'undo change vector size'

 AND NB.SID=USERENV('SID')) UNDO

  FROM DUAL;

 

 

 

4  实验过程

4.1  实验环境准备

--记录REDO和UNDO量的视图

CREATE OR REPLACE VIEW VW_REDO_UNDO_LHR AS

SELECT (SELECT NB.VALUE

          FROM V$MYSTAT NB, V$STATNAME ST

         WHERE NB.STATISTIC# = ST.STATISTIC#

           AND ST.NAME = 'redo size') REDO,

       (SELECT NB.VALUE

          FROM V$MYSTAT NB, V$STATNAME ST

         WHERE NB.STATISTIC# = ST.STATISTIC#

           AND ST.NAME = 'undo change vector size') UNDO

  FROM DUAL;

 

--准备中间表,T_A为500W,T_B为500W的数据量,T_A表删掉少量数据

DROP TABLE   T_A PURGE;

DROP TABLE   T_B PURGE;

CREATE TABLE T_A AS SELECT * FROM DBA_OBJECTS;

CREATE TABLE T_B AS SELECT * FROM DBA_OBJECTS;

 

INSERT INTO T_A SELECT * FROM T_A;

INSERT INTO T_A SELECT * FROM T_A;

INSERT INTO T_A SELECT * FROM T_A;

INSERT INTO T_A SELECT * FROM T_A;

INSERT INTO T_A SELECT * FROM T_A;

INSERT INTO T_A SELECT * FROM T_A;

COMMIT;

INSERT INTO T_B SELECT * FROM T_A;

DELETE FROM T_A WHERE OBJECT_ID>=90000;

COMMIT;

 

SELECT COUNT(1) FROM T_A;      --5548800

SELECT COUNT(1) FROM T_B;      --5668976

 

--记录测试结果

DROP TABLE T_RU_160929_LHR;

CREATE TABLE T_RU_160929_LHR (

    ID NUMBER PRIMARY KEY,

SQL_TYPES VARCHAR2(255),

SQL1 VARCHAR2(255),

SQL2 VARCHAR2(255),

SQL3 VARCHAR2(4000),

IS_DIRECT VARCHAR2(20),

IS_NOLOGGING VARCHAR2(20),

IS_PARALLEL VARCHAR2(20),

ARCH_REDO NUMBER, 

ARCH_UNDO NUMBER,

NOARCH_REDO NUMBER,

NOARCH_UNDO NUMBER,

ARCH_USE_TIME NUMBER,

NOARCH_USE_TIME NUMBER,

    SQL_EXPLAIN CLOB,

    COMMENTS VARCHAR2(255)

);

 

--插入要执行的SQL语句

 

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (1, 'CTAS', NULL, NULL, 'CREATE TABLE T_RU_CTAS_LHR AS SELECT * FROM T_B', 'Y', 'N', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (2, 'CTAS', NULL, NULL, 'CREATE TABLE T_RU_CTAS_LHR NOLOGGING AS SELECT * FROM T_B', 'Y', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (3, 'CTAS', NULL, NULL, 'CREATE TABLE T_RU_CTAS_LHR NOLOGGING PARALLEL 4 AS SELECT * FROM T_B', 'Y', 'Y', 'Y');

 

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (4, 'CI', NULL, NULL, 'CREATE INDEX IND_TA_LHR ON T_A(OBJECT_ID)', 'N', 'N', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (5, 'CI', NULL, NULL, 'CREATE INDEX IND_TA_LHR ON T_A(OBJECT_ID) NOLOGGING', 'N', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (6, 'CI', NULL, NULL, 'CREATE INDEX IND_TA_LHR ON T_A(OBJECT_ID) NOLOGGING PARALLEL 4', 'N', 'Y', 'Y');

 

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (7, 'MOVE', NULL, NULL, 'ALTER TABLE T_A MOVE', 'N', 'N', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (8, 'MOVE', NULL, NULL, 'ALTER TABLE T_A MOVE NOLOGGING', 'N', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (9, 'MOVE', NULL, NULL, 'ALTER TABLE T_A MOVE NOLOGGING PARALLEL 4', 'N', 'Y', 'Y');

 

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (10, 'INSERT', NULL, NULL, 'INSERT INTO T_A SELECT * FROM T_B', 'N', 'N', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (11, 'INSERT', 'ALTER TABLE T_A NOLOGGING', NULL, 'INSERT INTO T_A SELECT * FROM T_B', 'N', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (12, 'INSERT', NULL, NULL, 'INSERT /*+ APPEND */ INTO T_A SELECT * FROM T_B', 'Y', 'N', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (13, 'INSERT', 'ALTER TABLE T_A NOLOGGING', NULL, 'INSERT /*+ APPEND */ INTO T_A SELECT * FROM T_B', 'Y', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (14, 'INSERT', 'ALTER TABLE T_A NOLOGGING', NULL, 'INSERT /*+ PARALLEL(4) APPEND */ INTO T_A SELECT * FROM T_B', 'Y', 'Y', 'Y');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (15, 'INSERT', 'ALTER TABLE T_A NOLOGGING', 'ALTER SESSION ENABLE PARALLEL DML', 'INSERT /*+ PARALLEL(4) APPEND */ INTO T_A SELECT * FROM T_B', 'Y', 'Y', 'Y(PDML)');

 

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (16, 'UPDATE', NULL, NULL, 'UPDATE  T_A T SET T.DATA_OBJECT_ID =(SELECT TB.DATA_OBJECT_ID FROM T_B TB WHERE TB.OBJECT_ID = T.OBJECT_ID AND ROWNUM=1) WHERE T.OBJECT_ID <= 1000', 'N', 'N', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (17, 'UPDATE', NULL, NULL, 'UPDATE /*+ PARALLEL(4) */ T_A T SET T.DATA_OBJECT_ID =(SELECT TB.DATA_OBJECT_ID FROM T_B TB WHERE TB.OBJECT_ID = T.OBJECT_ID AND ROWNUM=1) WHERE T.OBJECT_ID <= 1000', 'N', 'N', 'Y(Queries)');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (18, 'UPDATE', 'ALTER TABLE T_A NOLOGGING', NULL, 'UPDATE  T_A T SET T.DATA_OBJECT_ID =(SELECT TB.DATA_OBJECT_ID FROM T_B TB WHERE TB.OBJECT_ID = T.OBJECT_ID AND ROWNUM=1) WHERE T.OBJECT_ID <= 1000', 'N', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (19, 'UPDATE', 'ALTER TABLE T_A NOLOGGING', NULL, 'UPDATE  /*+ PARALLEL(4) */ T_A T SET T.DATA_OBJECT_ID =(SELECT TB.DATA_OBJECT_ID FROM T_B TB WHERE TB.OBJECT_ID = T.OBJECT_ID AND ROWNUM=1) WHERE T.OBJECT_ID <= 1000', 'N', 'Y', 'Y(Queries)');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (20, 'UPDATE', 'ALTER SESSION ENABLE PARALLEL DML', NULL, 'UPDATE /*+ PARALLEL(4) */ T_A T SET T.DATA_OBJECT_ID =(SELECT TB.DATA_OBJECT_ID FROM T_B TB WHERE TB.OBJECT_ID = T.OBJECT_ID AND ROWNUM=1) WHERE T.OBJECT_ID <= 1000', 'N', 'N', 'Y(PDML)');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (21, 'UPDATE', 'ALTER TABLE T_A NOLOGGING', 'ALTER SESSION ENABLE PARALLEL DML', 'UPDATE /*+ PARALLEL(4) */ T_A T SET T.DATA_OBJECT_ID =(SELECT TB.DATA_OBJECT_ID FROM T_B TB WHERE TB.OBJECT_ID = T.OBJECT_ID AND ROWNUM=1) WHERE T.OBJECT_ID <= 1000', 'N', 'Y', 'Y(PDML)');

 

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (22, 'MERGE', 'ALTER TABLE T_A NOLOGGING', NULL, 'MERGE  INTO T_A T USING (SELECT TA.ROWID ROWIDS, MAX(TB.DATA_OBJECT_ID) DATA_OBJECT_ID FROM T_B TB, T_A TA WHERE TB.OBJECT_ID = TA.OBJECT_ID AND TA.OBJECT_ID <= 1000  GROUP BY TA.ROWID) T1 ON (T.ROWID = T1.ROWIDS)WHEN MATCHED THEN UPDATE SET T.DATA_OBJECT_ID = T1.DATA_OBJECT_ID', 'N', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (23, 'MERGE', 'ALTER TABLE T_A NOLOGGING', NULL, 'MERGE /*+ PARALLEL(4) */ INTO T_A T USING (SELECT TA.ROWID ROWIDS, MAX(TB.DATA_OBJECT_ID) DATA_OBJECT_ID FROM T_B TB, T_A TA WHERE TB.OBJECT_ID = TA.OBJECT_ID AND TA.OBJECT_ID <= 1000  GROUP BY TA.ROWID) T1 ON (T.ROWID = T1.ROWIDS)WHEN MATCHED THEN UPDATE SET T.DATA_OBJECT_ID = T1.DATA_OBJECT_ID', 'N', 'Y', 'Y(Queries)');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (24, 'MERGE', 'ALTER TABLE T_A NOLOGGING', 'ALTER SESSION ENABLE PARALLEL DML', 'MERGE /*+ PARALLEL(4) */ INTO T_A T USING (SELECT TA.ROWID ROWIDS, MAX(TB.DATA_OBJECT_ID) DATA_OBJECT_ID FROM T_B TB, T_A TA WHERE TB.OBJECT_ID = TA.OBJECT_ID AND TA.OBJECT_ID <= 1000  GROUP BY TA.ROWID) T1 ON (T.ROWID = T1.ROWIDS)WHEN MATCHED THEN UPDATE SET T.DATA_OBJECT_ID = T1.DATA_OBJECT_ID', 'N', 'Y', 'Y(PDML)');

 

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (25, 'DELETE', NULL, NULL, 'DELETE FROM  T_A T  WHERE T.OBJECT_ID IN  ( SELECT TB.OBJECT_ID FROM T_B TB) AND T.OBJECT_ID <= 1000', 'N', 'N', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (26, 'DELETE', NULL, NULL, 'DELETE /*+ PARALLEL(4) */ FROM  T_A T  WHERE T.OBJECT_ID IN  ( SELECT TB.OBJECT_ID FROM T_B TB) AND T.OBJECT_ID <= 1000', 'N', 'N', 'Y(Queries)');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (27, 'DELETE', 'ALTER TABLE T_A NOLOGGING', NULL, 'DELETE FROM  T_A T  WHERE T.OBJECT_ID IN  ( SELECT TB.OBJECT_ID FROM T_B TB) AND T.OBJECT_ID <= 1000', 'N', 'Y', 'N');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (28, 'DELETE', 'ALTER TABLE T_A NOLOGGING', NULL, 'DELETE /*+ PARALLEL(4) */ FROM  T_A T  WHERE T.OBJECT_ID IN  ( SELECT TB.OBJECT_ID FROM T_B TB) AND T.OBJECT_ID <= 1000', 'N', 'Y', 'Y(Queries)');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (29, 'DELETE', 'ALTER SESSION ENABLE PARALLEL DML', NULL, 'DELETE /*+ PARALLEL(4) */ FROM  T_A T  WHERE T.OBJECT_ID IN  ( SELECT TB.OBJECT_ID FROM T_B TB) AND T.OBJECT_ID <= 1000', 'N', 'N', 'Y(PDML)');

INSERT INTO T_RU_160929_LHR (ID, SQL_TYPES, SQL1, SQL2, SQL3, IS_DIRECT, IS_NOLOGGING, IS_PARALLEL) VALUES (30, 'DELETE', 'ALTER TABLE T_A NOLOGGING', 'ALTER SESSION ENABLE PARALLEL DML', 'DELETE /*+ PARALLEL(4) */ FROM  T_A T  WHERE T.OBJECT_ID IN  ( SELECT TB.OBJECT_ID FROM T_B TB) AND T.OBJECT_ID <= 1000', 'N', 'Y', 'Y(PDML)');

COMMIT;

插入完成后查询结果:

SELECT ID,

       SQL_TYPES,

       SQL1,

       SQL2,

       SQL3,

       IS_DIRECT,

       IS_NOLOGGING,

       IS_PARALLEL

  FROM T_RU_160929_LHR D

ORDER BY D.ID;

wps98E2.tmp 

下边的存过可以测试REDO和UNDO的量,至于该存过的算法大家自己看吧。

--创建存储过程,用来测试REDO量

CREATE OR REPLACE PROCEDURE PRO_TEST_RU_LHR AS

 

  V_REDO       NUMBER := 0;

  V_UNDO       NUMBER := 0;

  V_REDO1      NUMBER := 0;

  V_UNDO1      NUMBER := 0;

  V_ARCH       VARCHAR2(30);

  V_START_TIME NUMBER := 0;

  V_END_TIME   NUMBER := 0;

 

BEGIN

 

  SELECT D.LOG_MODE INTO V_ARCH FROM V$DATABASE D;

 

  FOR CUR IN (SELECT D.ID, D.SQL1, D.SQL2, D.SQL3

                FROM T_RU_160929_LHR D

               ORDER BY D.ID) LOOP

 

    BEGIN

      EXECUTE IMMEDIATE CUR.SQL1;

    EXCEPTION

      WHEN OTHERS THEN

        NULL;

    END;

    BEGIN

      EXECUTE IMMEDIATE CUR.SQL2;

    EXCEPTION

      WHEN OTHERS THEN

        NULL;

    END;

    SELECT DBMS_UTILITY.GET_TIME INTO V_START_TIME FROM DUAL;

    SELECT V.REDO, V.UNDO INTO V_REDO, V_UNDO FROM VW_REDO_UNDO_LHR V;

    EXECUTE IMMEDIATE CUR.SQL3;

    SELECT V.REDO, V.UNDO INTO V_REDO1, V_UNDO1 FROM VW_REDO_UNDO_LHR V;

    SELECT DBMS_UTILITY.GET_TIME INTO V_END_TIME FROM DUAL;

    ROLLBACK;

    IF V_ARCH = 'ARCHIVELOG' THEN

      UPDATE T_RU_160929_LHR T

         SET T.ARCH_REDO     = V_REDO1 - V_REDO,

             T.ARCH_UNDO     = V_UNDO1 - V_UNDO,

             T.ARCH_USE_TIME =

             (V_END_TIME - V_START_TIME) / 100,

             T.COMMENTS      = T.COMMENTS || 'ARCHIVELOG:' ||

                               (SELECT COUNT(1) FROM T_A) || '  '

       WHERE T.ID = CUR.ID;

   

    ELSE

      UPDATE T_RU_160929_LHR T

         SET T.NOARCH_REDO     = V_REDO1 - V_REDO,

             T.NOARCH_UNDO     = V_UNDO1 - V_UNDO,

             T.NOARCH_USE_TIME =

             (V_END_TIME - V_START_TIME) / 100,

             T.COMMENTS        = T.COMMENTS || 'NOARCHIVELOG:' ||

                                 (SELECT COUNT(1) FROM T_A) || '  '

       WHERE T.ID = CUR.ID;

   

    END IF;

    COMMIT;

    EXECUTE IMMEDIATE 'ALTER TABLE T_A LOGGING';

    EXECUTE IMMEDIATE 'ALTER SESSION DISABLE PARALLEL DML';

    EXECUTE IMMEDIATE 'ALTER SYSTEM FLUSH BUFFER_CACHE';

    BEGIN

      EXECUTE IMMEDIATE 'DROP INDEX IND_TA_LHR';

    EXCEPTION

      WHEN OTHERS THEN

        NULL;

    END;

    BEGIN

      EXECUTE IMMEDIATE 'DROP TABLE T_RU_CTAS_LHR PURGE';

    EXCEPTION

      WHEN OTHERS THEN

        NULL;

    END;

  END LOOP;

 

END;

4.2  开始实验

4.2.1  归档模式

增加日志组的个数,避免因为日志切换导致的等待。

SYS@lhrdb> select * from v$version;

 

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

PL/SQL Release 11.2.0.4.0 - Production

CORE    11.2.0.4.0      Production

TNS for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production

NLSRTL Version 11.2.0.4.0 - Production

 

SYS@lhrdb> select GROUP#,BYTES,STATUS from v$log;

 

    GROUP#      BYTES STATUS

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

         1  104857600 ACTIVE

         2  104857600 ACTIVE

         3  104857600 ACTIVE

         4  104857600 CURRENT

         5  104857600 ACTIVE

         6  104857600 ACTIVE

 

6 rows selected.

 

SYS@lhrdb> archive log list;

Database log mode              Archive Mode

Automatic archival             Enabled

Archive destination            USE_DB_RECOVERY_FILE_DEST

Oldest online log sequence     401

Next log sequence to archive   406

Current log sequence           406

SYS@lhrdb> SET TIMING ON

SYS@lhrdb> exec PRO_TEST_RU_LHR;

 

PL/SQL procedure successfully completed.

 

Elapsed: 00:12:49.83

SYS@lhrdb>

在PL/SQL DEVELOPER中查询结果:

SELECT D.*

  FROM T_RU_160929_LHR D

 ORDER BY D.ID;

4.2.2  非归档模式

SYS@lhrdb> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@lhrdb> startup mount

ORACLE instance started.

 

Total System Global Area 1720328192 bytes

Fixed Size                  2247072 bytes

Variable Size             486540896 bytes

Database Buffers         1224736768 bytes

Redo Buffers                6803456 bytes

Database mounted.

 

SYS@lhrdb> alter database noarchivelog;

 

Database altered.

 

SYS@lhrdb> alter database open;

 

Database altered.

 

SYS@lhrdb> archive log list;

Database log mode              No Archive Mode

Automatic archival             Disabled

Archive destination            USE_DB_RECOVERY_FILE_DEST

Oldest online log sequence     419

Current log sequence           424

SYS@lhrdb>

 

 

SYS@lhrdb> set timing on

SYS@lhrdb> exec PRO_TEST_RU_LHR;

 

PL/SQL procedure successfully completed.

 

Elapsed: 00:13:31.67

在PL/SQL DEVELOPER中查询结果:

SELECT D.*

  FROM T_RU_160929_LHR D

 ORDER BY D.ID;

 

以上测试过程,可以多做几次,然后取其平均值,多次测试前将结果表清空:

UPDATE T_RU_160929_LHR T

   SET T.ARCH_REDO       = '',

       T.ARCH_UNDO       = '',

       T.ARCH_USE_TIME   = '',

       T.NOARCH_REDO     = '',

       T.NOARCH_UNDO     = '',

       T.NOARCH_USE_TIME = '',

       T.COMMENTS        = '';

COMMIT;

 

4.3  实验结果

wps98F3.tmp

根据以上的实验可以得到一些结论:关于表日志模式(LOGGING/NOLOGGING)、插入模式(APPEND/NOAPPEND)、数据库运行模式(归档/非归档)和并行模式下,REDO、UNDO和执行速度的情况大约如下表所示:

NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和执行速度的比较_实验结果_LHR

5  结论

(一)关于效率的结论:

1、INSERT INTO: 在APPEND提示的情况下,NOLOGGING或NOARCHIVELOG满足一个即产生少量的REDO和UNDO;另外PARALLEL默认是以DIRECT的方式进行加载数据的,一般在并行情况下SQL执行速度提高。

2、CTAS:CTAS本身就是一种DIRECT的操作,归档模式+NOLOGGING模式产生少量REDO;并行模式下时间大幅度减少,但生成的REDO和UNDO成倍增长。

3、ALTER TABLE ... MOVE:ARCHIVELOG+NOLOGGING模式产生少量REDO;并行模式下时间大幅度减少,但生成的REDO和UNDO成倍增长。

4、CREATE INDEX:ARCHIVELOG+NOLOGGING模式产生少量REDO;并行模式下时间大幅度减少,但生成的REDO和UNDO成倍增长。

5、UPDATE:任何组合都会生成大量UNDO、大量REDO;有关并行的性能需要查询执行计划再做定夺。

6、DELETE:任何组合都会生成大量UNDO、大量REDO;加上并行可以大幅度提高SQL的执行速度。

7、MERGE:在关联更新的情况下,MERGE语句的非关联形式的性能比UPDATE要高,若加上并行性能更好。

8、总体而言,非归档比归档模式下性能高

 

(二)关于属性NOLOGGING和并行度的结论:

1、对于形如:CREATE TABLE TT NOLOGGING PARALLEL 4 AS SELECT * FROM DBA_OBJECTS; 或CREATE INDEX IDNX11 ON TT(OBJECT_ID) NOLOGGING PARALLEL 4;的SQL语句而言,创建的表或索引的并行度是4,日志模式是NOLOGGING,所以,生产库上对于重要的表和索引需要修改为LOGGING,并行度可以根据需要来修改,ALTER TABLE TT LOGGING NOPARALLEL;或ALTER INDEX IDNX11 LOGGING NOPARALLEL;

2、对于形如:ALTER TABLE TT MOVE NOLOGGING PARALLEL 4;或ALTER INDEX IDNX11 REBUILD NOLOGGING PARALLEL 4;的SQL语句而言,修改后的表的并行度依然为原来的并行度,但是索引的并行度是4,而日志模式都是NOLOGGING,所以,生产库上对于重要的表和索引需要修改为LOGGING,并行度可以根据需要来修改,ALTER TABLE TT LOGGING NOPARALLEL;或ALTER INDEX IDNX11 LOGGING NOPARALLEL;

总之一句话,若执行了上边形式的SQL语句后,最好都修改一下表或索引的并行度及其日志模式。

 

(三)APPEND使用注意事项:

1、建议不要经常使用APPEND,这样表空间会一直在高水位上,除非你这个表只插不删。

2、以APPEND方式插入记录后,要执行COMMIT,才能对表进行查询。否则会出现错误:ORA-12838: 无法在并行模式下修改之后读/修改对象。

3、APPEND对INSERT INTO ... VALUES语句不起作用,需要使用11gR2的APPEND_VALUES来提示才可以直接路径加载,注意:APPEND_VALUES对INSERT INTO ... SELECT也起作用。

4、APPEND使用HWM之上的块,减少了搜索FREELIST上块的时间。

5、在归档模式下:NOLOGGING+APPEND才会显著减少REDO数量;在非归档模式下:单独APPEND即可减少REDO数量。

6、APPEND不会减少相关表的索引上产生的REDO数量。

7、APPEND的插入操作是给表加上6级排它锁,会阻塞表上的所有DML语句。

8、每提交一次,就会取一个新的BLOCK存放,高水位就上推一个BLOCK,若在LOOP循环中,外部循环100W次,但是每循环一次只有一行符合条件的数据插入,这样,大量单条/*+APPEND*/插入,就会使得表急剧增大,除对INSERT本身造成性能影响之外,对以后的SELECT、UPDATE、DELETE更是带来更巨大的性能影响。 

 

(四)NOLOGGING使用注意事项:

1、NOLOGGING插完后最好对表做个备份。生产上重要的表不建议设置NOLOGGING属性。

2、如果库处在FORCE LOGGING模式下,此时的NOLOGGING方式是无效的。

 

(五)PDML使用注意事项:

1、必须使用ALTER SESSION ENABLE PARALLEL DML;才可以启动PDML。

 

 

  About Me

...............................................................................................................................

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/viewspace-2125815/

● 本文博客园地址:http://www.cnblogs.com/lhrbest/p/5924743.html

● 本文pdf版:http://yunpan.cn/cdEQedhCs2kFz (提取码:ed9b)

● 小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● QQ群:230161599     微信群:私聊

● 联系我请加QQ好友(642808185),注明添加缘由

● 于 2016-09-27 10:00 ~ 2016-09-30 19:00 在中行完成

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解!

● 【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】

...............................................................................................................................

手机长按下图识别二维码或微信客户端扫描下边的二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,免费学习最实用的数据库技术。

wps98F5.tmp