【知識點整理】Oracle中NOLOGGING、APPEND、ARCHIVE和PARALLEL下,REDO、UNDO和執行速度的比較
1 BLOG文檔結構圖
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 REDO和UNDO生成量的查詢
說明:反映UNDO、REDO占用量的統計指標是:
UNDO:undo change vector size
REDO:redo size
1、查看全局數據庫REDO生成量,可以通過V$SYSSTAT視圖查詢
SELECT NAME,
VALUE
FROM V$SYSSTAT
WHERE NAME = 'redo size';
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; |
下邊的存過可以測試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 實驗結果
根據以上的實驗可以得到一些結論:關於表日志模式(LOGGING/NOLOGGING)、插入模式(APPEND/NOAPPEND)、數據庫運行模式(歸檔/非歸檔)和並行模式下,REDO、UNDO和執行速度的情況大約如下表所示:
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,免費學習最實用的數據庫技術。 |