Besides brevity - does MERGE actually give performance benefits over a traditional INSERT-UPDATE approach ?
SQL> create table T1 ( 2 x1 number primary key, 3 y1 number ); Table created. SQL> create table T2 ( 2 x2 number primary key, 3 y2 number ); Table created. SQL> insert into t1 2 select rownum,rownum from all_objects 3 where rownum <= 10000; 10000 rows created. SQL> insert into t2 2 select rownum,rownum+1 from all_objects 3 where rownum <= 20000; 20000 rows created. SQL> analyze table t1 estimate statistics; Table analyzed. SQL> analyze table t2 estimate statistics; Table analyzed. SQL> begin 2 update t1 3 set y1 = ( select y2 from t2 where x2 = t1.x1 ) 4 where x1 in ( select x2 from t2 ); 5 6 insert into t1 7 select * from t2 8 where x2 not in ( select x1 from t1 ) ; 9 end; 10 / PL/SQL procedure successfully completed. SQL> roll; Rollback complete. SQL> begin 2 MERGE INTO t1 3 USING t2 4 ON (t1.x1 = t2.x2) 5 WHEN MATCHED THEN 6 UPDATE SET t1.y1 = t2.y2 7 WHEN NOT MATCHED THEN 8 INSERT (x1,y1) VALUES (x2,y2) ; 9 end; 10 / PL/SQL procedure successfully completed.
Now we look at the trace file content
UPDATE T1 SET Y1 = ( SELECT Y2 FROM T2 WHERE X2 = T1.X1 ) WHERE X1 IN ( SELECT X2 FROM T2 ) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 3 0.01 0.00 0 0 0 0 Execute 3 3.81 5.46 49 100278 51214 50000 Fetch 0 0.00 0.00 0 0 0 0 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 6 3.82 5.46 49 100278 51214 50000 INSERT INTO T1 SELECT * FROM T2 WHERE X2 NOT IN ( SELECT X1 FROM T1 ) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 3 0.01 0.00 0 0 0 0 Execute 3 0.59 0.94 45 342 19623 10000 Fetch 0 0.00 0.00 0 0 0 0 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 6 0.60 0.94 45 342 19623 10000 MERGE INTO T1 USING T2 ON (T1.X1 = T2.X2) WHEN MATCHED THEN UPDATE SET T1.Y1 = T2.Y2 WHEN NOT MATCHED THEN INSERT (X1,Y1) VALUES (X2,Y2) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 3 0.00 0.00 0 0 0 0 Execute 3 2.73 6.24 23 310 70827 60000 Fetch 0 0.00 0.00 0 0 0 0 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 6 2.73 6.25 23 310 70827 60000Looks like MERGE is our guy