<b>Lets try it out -- turns out the insert component could write above the high water mark, but the update will always and forever be an update
I am in NOarchive log mode for this test -- so the absence of redo indicates it did an append:</b>
ops$tkyte@ORA9IR2> create table t1
2 as
3 select object_id, rpad('*',80,'*') data
4 from all_objects;
Table created.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> alter table t1 parallel 2;
Table altered.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> create table t2
2 as
3 select * from t1 where 1=0;
Table created.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> alter table t2 parallel 2;
Table altered.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> ALTER SESSION ENABLE PARALLEL DML;
Session altered.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> column value new_val V
ops$tkyte@ORA9IR2> select * from v$sysstat where name = 'redo size';
STATISTIC# NAME CLASS VALUE
---------- ------------------------------ ---------- ----------
115 redo size 2 2498449472
ops$tkyte@ORA9IR2> insert /*+ append */ into t2 select * from t1;
27949 rows created.
ops$tkyte@ORA9IR2> select value, value-&v diff from v$sysstat where name = 'redo size';
old 1: select value, value-&v diff from v$sysstat where name = 'redo size'
new 1: select value, value-2498449472 diff from v$sysstat where name = 'redo size'
VALUE DIFF
---------- ----------
2498548752 99280
<b>just a baseline, an insert append of these rows generated about 99k of redo</b>
ops$tkyte@ORA9IR2> rollback;
Rollback complete.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select * from v$sysstat where name = 'redo size';
STATISTIC# NAME CLASS VALUE
---------- ------------------------------ ---------- ----------
115 redo size 2 2498561448
ops$tkyte@ORA9IR2> merge /*+ append parallel( t2 ) */ into t2
2 using t1
3 on ( t1.object_id = t2.object_id )
4 when matched then update set data = substr(t1.data,1,79)
5 when not matched then insert values ( t1.object_id, t1.data );
27949 rows merged.
ops$tkyte@ORA9IR2> select value, value-&v diff from v$sysstat where name = 'redo size';
old 1: select value, value-&v diff from v$sysstat where name = 'redo size'
new 1: select value, value-2498561448 diff from v$sysstat where name = 'redo size'
VALUE DIFF
---------- ----------
2498680404 118956
<b>and the merge -- about 118k -- given that a conventional path operation:</b>
ops$tkyte@ORA9IR2> rollback;
Rollback complete.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select * from v$sysstat where name = 'redo size';
STATISTIC# NAME CLASS VALUE
---------- ------------------------------ ---------- ----------
115 redo size 2 2498688004
ops$tkyte@ORA9IR2> merge /*+ noappend noparallel( t2 ) */ into t2
2 using t1
3 on ( t1.object_id = t2.object_id )
4 when matched then update set data = substr(t1.data,1,79)
5 when not matched then insert values ( t1.object_id, t1.data );
27949 rows merged.
ops$tkyte@ORA9IR2> select value, value-&v diff from v$sysstat where name = 'redo size';
old 1: select value, value-&v diff from v$sysstat where name = 'redo size'
new 1: select value, value-2498688004 diff from v$sysstat where name = 'redo size'
VALUE DIFF
---------- ----------
2501595832 2907828
<b>generated 2.9meg, it is safe to say "the merge inserted in append mode" above</b>
ops$tkyte@ORA9IR2> commit;
Commit complete.
<b>but now we have committed.... so:</b>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select * from v$sysstat where name = 'redo size';
STATISTIC# NAME CLASS VALUE
---------- ------------------------------ ---------- ----------
115 redo size 2 2501595916
ops$tkyte@ORA9IR2> merge /*+ append parallel( t2 ) */ into t2
2 using t1
3 on ( t1.object_id = t2.object_id )
4 when matched then update set data = substr(t1.data,1,79)
5 when not matched then insert values ( t1.object_id, t1.data );
27949 rows merged.
ops$tkyte@ORA9IR2> select value, value-&v diff from v$sysstat where name = 'redo size';
old 1: select value, value-&v diff from v$sysstat where name = 'redo size'
new 1: select value, value-2501595916 diff from v$sysstat where name = 'redo size'
VALUE DIFF
---------- ----------
2512736924 11141008
<b>that merge was in fact an UPDATE and the redo reflects that</b>
ops$tkyte@ORA9IR2> commit;
Commit complete.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select * from v$sysstat where name = 'redo size';
STATISTIC# NAME CLASS VALUE
---------- ------------------------------ ---------- ----------
115 redo size 2 2512737680
ops$tkyte@ORA9IR2> merge /*+ noappend noparallel( t2 ) */ into t2
2 using t1
3 on ( t1.object_id = t2.object_id )
4 when matched then update set data = substr(t1.data,1,79)
5 when not matched then insert values ( t1.object_id, t1.data );
27949 rows merged.
ops$tkyte@ORA9IR2> select value, value-&v diff from v$sysstat where name = 'redo size';
old 1: select value, value-&v diff from v$sysstat where name = 'redo size'
new 1: select value, value-2512737680 diff from v$sysstat where name = 'redo size'
VALUE DIFF
---------- ----------
2523941844 11204164
ops$tkyte@ORA9IR2> set autotrace off
<b>actually, hmmm, i just tested without parallel dml and sure enough, the APPEND hint does in fact modify the behaviour of the MERGE, interesting -- every time I answer something with a test case to back it up, I goof.
proof further that statements without supporting evidence are just -- well, statements
thanks for making me look just a tad deeper at this.</b>