一.NOLOGGING说明
在对大表插入数据的时候,经常会用到nologging选项。Nologging并不是不产生redo,nologging+direct只是不会对数据产生redo(但依然有其他的redo)。
同理logging+direct下undo也是大大地减少,减少的是数据的undo,这里强调的是数据本身的undo,就如同redo的减少也一样,是数据本身的redo,这和数据库是否产生redo和undo是不同的概念,比如空间分配的redoandundo,这就不是数据本身的变化。
在非归档模式下,对于nologging和logging模式,只有使用append,才不会对数据生成redo。
在归档模式下,只有将表置于nologging模式,并且使用append才不会对数据生成redo.
二.归档模式下的示例
两个查询用的脚本
--new.sql
columnOLD_VALUEnew_valueOLD_VALUE
selectvalueOLD_VALUE
fromv$mystat,v$statname
wherev$mystat.statistic#=v$statname.statistic#
andv$statname.name='redosize';
--diff.sql
select(value-&OLD_VALUE)OLD_VALUE
fromv$mystat,v$statname
wherev$mystat.statistic#=v$statname.statistic#
andv$statname.name='redosize';
数据库运行在归档模式
SQL>archiveloglist
数据库日志模式存档模式
自动存档启用
存档终点d:/archivelog
最早的联机日志序列125
下一个存档日志序列127
当前日志序列127
2.1CreateTABLE
SQL>@?/new.sql
OLD_VALUE
----------
8535492
SQL>createtableT_NOLOGnologgingasselect*fromall_objects;
表已创建。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-8535492)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
83496
注:REDOSIZE=83496
SQL>@?/new.sql
OLD_VALUE
----------
8618988
SQL>createtableT_LOGloggingasselect*fromall_objects;
表已创建。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-8618988)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8491836
注:REDOSIZE=8491836
总结:通过上面的2个例子,可以看出用nologging创建表,不会对数据生成redo,仅对数据字典生成redo.
createtablewithnologging...notgenerateredo,justgeneratefordatadictionary
2.2DELETE
SQL>@?/new.sql
OLD_VALUE
----------
17110824
SQL>DELETEFROMT_NOLOG;
已删除71711行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-17110824)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
26592364
注:REDOSIZE=26592364
SQL>@?/new.sql
OLD_VALUE
----------
43703188
SQL>DELETEFROMT_LOG;
已删除71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-43703188)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
26592560
注:REDOSIZE=26592560
2.3INSERT
SQL>@?/new.sql
OLD_VALUE
----------
70295748
SQL>INSERTINTOT_NOLOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-70295748)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8169900
注:REDOSIZE=8169900
SQL>@?/new.sql
OLD_VALUE
----------
78465648
SQL>INSERTINTOT_LOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-78465648)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8169796
注:REDOSIZE=8169796
2.4UPDATE
SQL>@?/new.sql
OLD_VALUE
----------
86635444
SQL>UPDATET_NOLOGSETOBJECT_ID=1;
已更新71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-86635444)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
24323896
注:REDOSIZE=24323896
SQL>@?/new.sql
OLD_VALUE
----------
110959340
SQL>UPDATET_LOGSETOBJECT_ID=1;
已更新71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-110959340)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
36490988
注:REDOSIZE=20911424
总结:insert/update/delete的DML操作,在logging和nologging上没有区别
OnDMLinsert/update/deleteredosizewithnologgingnotdifference...withlogging.
2.5Showcase"APPEND"hints
2.5.1tableNOLOGGINGandnotuseAPPENDhints
SQL>@?/new.sql
OLD_VALUE
----------
147450328
SQL>INSERTINTOT_NOLOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-147450328)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8325816
注:REDOSIZE=8325816
SQL>@?/new.sql
OLD_VALUE
----------
155776144
SQL>INSERT/*+APPEND*/INTOT_NOLOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-155776144)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
14852
注:REDOSIZE=14852,采用append后,redosize大幅减小
2.5.2tableLOGGING,anduseAPPENDhints
SQL>@?/new.sql
OLD_VALUE
----------
155790996
SQL>INSERT/*+APPEND*/INTOT_LOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-155790996)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8406068
注:REDOSIZE=8640396,redosize没什么变化
将表改为nologging模式,在查看
SQL>@?/new.sql
OLD_VALUE
----------
164200200
SQL>INSERT/*+APPEND*/INTOT_LOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-164200200)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
15012
注:REDOSIZE=27956
总结:通过实验看出,
对于logging模式,使用appendhint在生成redo上没有什么变化
对于nologging模式,使用appendhint对数据没有生成redo,仅对数据字典生成了redo.
APPENDhintsontable"logging"notdifference(generateredo).
If"altertablenologging"before,andtheninsert(append)...it'sworkwithnologging(notgenerateredo,justredofordatadictionary).
三.非归档模式下的示例
SQL>archiveloglist
数据库日志模式非存档模式
自动存档禁用
存档终点d:/archivelog
最早的联机日志序列129
当前日志序列131
3.1CreateTABLE
SQL>@?/new.sql
OLD_VALUE
----------
113788
SQL>createtableT_NOLOGnologgingasselect*fromall_objects;
表已创建。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-113788)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
87244
注:redosize=87244
SQL>@?/new.sql
OLD_VALUE
----------
201032
SQL>createtableT_LOGloggingasselect*fromall_objects;
表已创建。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-201032)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
81324
注:redosize=81324
总结:在非归档模式下,createtable在nologging和logging模式差别不大。
Whencreatetable(noarchivemode)LOGGINGtablenotdifferentNOLOGGINGtable
3.2DML--DELETE
SQL>@?/new.sql
OLD_VALUE
----------
282356
SQL>DELETEFROMT_NOLOG;
已删除71711行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-282356)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
26591628
注:redosize=26591628
SQL>@?/new.sql
OLD_VALUE
----------
26873984
SQL>DELETEFROMT_LOG;
已删除71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-26873984)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
26590272
注:redosize=26590272
3.3DML--INSERT
SQL>@?/new.sql
OLD_VALUE
----------
53464256
SQL>INSERTINTOT_NOLOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-53464256)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8170184
注:redosize=8170184
SQL>@?/new.sql
OLD_VALUE
----------
61634440
SQL>INSERTINTOT_LOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-61634440)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8169840
注:redosize=8169840
3.4DML--UPDATE
SQL>@?/new.sql
OLD_VALUE
----------
69804280
SQL>UPDATET_NOLOGSETOBJECT_ID=1;
已更新71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-69804280)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
20164888
注:redosize=20164888
SQL>@?/new.sql
OLD_VALUE
----------
89969168
SQL>UPDATET_LOGSETOBJECT_ID=1;
已更新71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-89969168)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
21674776
注:redosize=21674776
总结:对于INSERT/UPDATE/DELETE的DML操作,nologging和logging模式没有什么区别
OnDMLINSERT/UPDATE/DELETEnotdifferentbetweenNOLOGGINGandLOGGING
3.5INSERT/*+APPEND*/
SQL>@?/new.sql
OLD_VALUE
----------
111643944
SQL>INSERTINTOT_NOLOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-111643944)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8325816
注:redosize=8325816
SQL>@?/new.sql
OLD_VALUE
----------
119969760
SQL>INSERT/*+APPEND*/INTOT_NOLOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-119969760)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
14896
注:redosize=14896,减小很多
SQL>@?/new.sql
OLD_VALUE
----------
119984656
SQL>INSERTINTOT_LOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-119984656)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
8325832
注:redosize=8325832
SQL>@?/new.sql
OLD_VALUE
----------
128310488
SQL>INSERT/*+APPEND*/INTOT_LOGSELECT*FROMALL_OBJECTS;
已创建71712行。
SQL>@?/diff
原值1:select(value-&OLD_VALUE)OLD_VALUEfromv$mystat,v$statnamewhere
新值1:select(value-128310488)OLD_VALUEfromv$mystat,v$statnamewhere
OLD_VALUE
----------
14880
注:redosize=14880
总结:对于非归档模式,对于nologging和logging模式,只有使用append,才不会对数据生成redo。
对于归档模式,只有将表置于nologging模式,并且使用append才不会对数据生成redo.
一点注意的地方:
如果直接加载的表上有索引,Oracle不会像加载数据的方式那样来处理索引的数据,但是它同样需要维护一个索引,这个成本很高,同时会生成很多的redo。
所以当使用直接加载时,通常是针对一些数据量非常大的表。如果这些表存在索引,将会带来很大的性能影响,这时可以考虑先将索引disable或者drop掉,等加载数据后,之后在重新建立索引。
OnNoArchiveMode,Don'tmindtablesbenologging/logging...justuse/*+APPEND*/,thatwillnotgenerateredo(justdatadictionary)
OnArchiveMode,TABLEsmustbenologging...anduse/*+APPEND*/,thatwillnotgenerateredo(justdatadictionary)
NOLOGGING:Oraclewillgenerateaminimalnumberofredologentriesinordertoprotectthedatadictionary,andtheoperationwillprobablyrunfaster.Loggingcanbedisabledatthetablelevelorthetablespacelevel.
Ifitisdoneatthetablespacelevelthenwecreateindexesortablesinthistablespace;theywillbeinNOLOGGINGmode.
AtableoranindexcanbecreatedwithNOLOGGINGmodeoritcanbealteredusingALTERTABLE/INDEXNOLOGGING.
NOLOGGINGisactiveinthefollowingsituationsandwhilerunningoneofthefollowingcommandsbutnotafterthat.
-DIRECTLOAD(SQL*Loader)
-DIRECTLOADINSERT(usingAPPENDhint)
-CREATETABLE...ASSELECT
-CREATEINDEX
-ALTERTABLEMOVE
-ALTERTABLE...MOVEPARTITION
-ALTERTABLE...SPLITPARTITION
-ALTERTABLE...ADDPARTITION(ifHASHpartition)
-ALTERTABLE...MERGEPARTITION
-ALTERTABLE...MODIFYPARTITION,ADDSUBPARTITON,COALESCESUBPARTITON,REBUILDUNUSABLEINDEXES
-ALTERINDEX...SPLITPARTITION
-ALTERINDEX...REBUILD
-ALTERINDEX...REBUILDPARTITION
Loggingisstoppedonlywhileoneofthecommandsaboveisrunning.
Soifauserrunsthis:ALTERINDEXnew_indexNOLOGGING.
Theactualrebuildoftheindexdoesnotgenerateredo(alldatadictionarychangesassociatedwiththerebuildwilldo)butafterthatanyDMLontheindexwillgenerateredothisincludesdirectloadinsertonthetablewhichtheindexbelongsto.
AllthefollowingstatementswillgenerateredodespitethefactthetableisinNOLOGGINGmode:
-INSERTINTOnew_table_nolog_test...,
-UPDATEnew_table_nolog_testSET...,
-DELETEFROMnew_table_nolog_test..
Thefollowingwillnotgenerateredo(exceptfromdictionarychangesandindexes):
-INSERT/*+APPEND+/...
-ALTERTABLEnew_table_nolog_testMOVE...
-ALTERTABLEnew_table_nolog_testMOVEPARTITION...
整理自网络
------------------------------------------------------------------------------
Blog:http://blog.csdn.net/tianlesoftware
网上资源:http://tianlesoftware.download.csdn.net
相关视频:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx
DBA1群:62697716(满);DBA2群:62697977