以前看到过merge into 不过都没怎么留意过,今天看到了,赶紧记录下:

SQL> select version from product_component_version;

VERSION

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

10.2.0.1.0

10.2.0.1.0

10.2.0.1.0

10.2.0.1.0

SQL> create table merge1 (id number,name varchar2(30 char),partment varchar2(1

char));

表已创建。

SQL> create table merge2 (id number,name varchar2(30 char),partment varchar2(1

char));

表已创建。

SQL> insert into merge1 values(100,'tom','A');

已创建 1 行。

SQL> insert into merge1 values(101,'cat','A');

已创建 1 行。

SQL> insert into merge1 values(102,'dog','B');

已创建 1 行。

SQL> insert into merge1 values(103,'fish','C');

已创建 1 行。

SQL> commit;

提交完成。

SQL> insert into merge2 values(103,'fish','D');

已创建 1 行。

SQL> insert into merge2 values(102,'dog','B');

已创建 1 行。

SQL> insert into merge2 values(101,'cat','A');

已创建 1 行。

SQL> insert into merge2 values(108,'dog','B');

已创建 1 行。

SQL> commit;

----不带where子句

SQL>  merge into merge1

2     using merge2

3   on (merge1.id = merge2.id)

4   when matched then

5     update

6    set merge1.name = merge2.name;

3 行已合并。

SQL> rollback;

回退已完成。

---带where子句

SQL>   merge into merge1 a

2    using merge2 b

3   on (a.id = b.id)

4   when matched then

5    update

6    set a.name = b.name

7   where a.name <> b.name;

0 行已合并。

------如果要更新b表,这样写会出错

SQL>    merge into merge1 a

2     using merge2 b

3    on (a.id = b.id)

4    when matched then

5     update

6     set b.name = a.name;

set b.name = a.name

*

第 6 行出现错误:

ORA-00904: "B"."NAME": 标识符无效

这里有个疑问,假设merge1表有800W数据,而merge2表只有20W数据。我要更新merge2表的数据,保持和merge1表一致的话,难道只能把merge1表作为基表?

SQL>    merge into merge2 a

2     using merge2 1

3    on (a.id = b.id)

4    when matched then

5     update

6     set a.name = b.name;

这样写,我感觉性能大打折扣,要对比800W次。这就是说merge into只有在大表的数据需要和小表的数据保持一致的情况下才更能更好的提升性能?而小表的数据需要和大表保持一致时,merge into 不是理想的选择?

SQL>  merge into merge1

2    using merge2

3   on (merge1.id = merge2.id)

4   when not matched then

5   insert

6   values(merge2.id,merge2.name,merge2.partment)

7  where name = 'dog';

merge into merge1

*

第 1 行出现错误:

ORA-38102: INSERT WHERE 子句中的列无效: "MERGE1"."NAME"

where条件的列必须声明,否则回认为是merge1的列

SQL>  merge into merge1

2    using merge2

3   on (merge1.id = merge2.id)

4   when not matched then

5   insert

6   values(merge2.id,merge2.name,merge2.partment)

7  where merge2.name = 'dog';

1 行已合并。

SQL>  merge into merge1

2    using merge2

3   on (merge1.id = merge2.id)

4   when not matched then

5   insert

6   values(merge2.id,merge2.name,merge2.partment)

7   when matched then

8   update

9   set merge1.name = merge2.name,

10     merge1.partment = merge2.partment;

4 行已合并。

SQL> rollback;

回退已完成。

SQL>  merge into merge1

2    using merge2

3   on (merge1.id = merge2.id)

4   when not matched then

5   insert

6   values(merge2.id,merge2.name,merge2.partment)

7   when matched then

8   update

9   set merge1.name = merge2.name

10  delete

11  where (merge1.name = 'cat');

4 行已合并。

下面看看执行计划:

----第一次的执行计划

SQL> rollback

2  ;

回退已完成。

SQL> set autotrace on;

SQL> alter system flush shared_pool;

系统已更改。

SQL>  insert into  merge1

2    select * from merge2

3        where not exists (select * from  merge1 where merge1.id = merge2.id)

已创建 1 行。

执行计划

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

Plan hash value: 3303303066

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

| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | INSERT STATEMENT   |        |     1 |    70 |     5  (20)| 00:00:01 |

|*  1 |  HASH JOIN ANTI    |        |     1 |    70 |     5  (20)| 00:00:01 |

|   2 |   TABLE ACCESS FULL| MERGE2 |     4 |   228 |     2   (0)| 00:00:01 |

|   3 |   TABLE ACCESS FULL| MERGE1 |     5 |    65 |     2   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

1 - access("MERGE1"."ID"="MERGE2"."ID")

Note

-----

- dynamic sampling used for this statement

统计信息

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

1510  recursive calls

3  db block gets

261  consistent gets

0  physical reads

0  redo size

675  bytes sent via SQL*Net to client

657  bytes received via SQL*Net from client

4  SQL*Net roundtrips to/from client

34  sorts (memory)

0  sorts (disk)

1  rows processed

SQL> rollback;

回退已完成。

----第二次的执行计划

SQL> alter system flush shared_pool;

系统已更改。

SQL>  merge into merge1

2        using merge2

3        on (merge1.id = merge2.id)

4          when not matched then

5          insert

6         values(merge2.id,merge2.name,merge2.partment);

1 行已合并。

执行计划

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

Plan hash value: 1212982789

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

| Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | MERGE STATEMENT      |        |     4 |   456 |     5  (20)| 00:00:01 |

|   1 |  MERGE               | MERGE1 |       |       |            |          |

|   2 |   VIEW               |        |       |       |            |          |

|*  3 |    HASH JOIN OUTER   |        |     4 |   504 |     5  (20)| 00:00:01 |

|   4 |     TABLE ACCESS FULL| MERGE2 |     4 |   228 |     2   (0)| 00:00:01 |

|   5 |     TABLE ACCESS FULL| MERGE1 |     5 |   345 |     2   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

3 - access("MERGE1"."ID"(+)="MERGE2"."ID")

Note

-----

- dynamic sampling used for this statement

统计信息

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

605  recursive calls

3  db block gets

89  consistent gets

0  physical reads

0  redo size

659  bytes sent via SQL*Net to client

708  bytes received via SQL*Net from client

4  SQL*Net roundtrips to/from client

9  sorts (memory)

0  sorts (disk)

1  rows processed

SQL> rollback;

回退已完成。

SQL> alter system flush shared_pool;

系统已更改。

SQL>  merge into merge1

2        using merge2

3        on (merge1.id = merge2.id)

4          when not matched then

5          insert

6         values(merge2.id,merge2.name,merge2.partment);

1 行已合并。

执行计划

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

Plan hash value: 1212982789

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

| Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | MERGE STATEMENT      |        |     4 |   456 |     5  (20)| 00:00:01 |

|   1 |  MERGE               | MERGE1 |       |       |            |          |

|   2 |   VIEW               |        |       |       |            |          |

|*  3 |    HASH JOIN OUTER   |        |     4 |   504 |     5  (20)| 00:00:01 |

|   4 |     TABLE ACCESS FULL| MERGE2 |     4 |   228 |     2   (0)| 00:00:01 |

|   5 |     TABLE ACCESS FULL| MERGE1 |     5 |   345 |     2   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

3 - access("MERGE1"."ID"(+)="MERGE2"."ID")

Note

-----

- dynamic sampling used for this statement

统计信息

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

605  recursive calls

3  db block gets

89  consistent gets

0  physical reads

0  redo size

659  bytes sent via SQL*Net to client

708  bytes received via SQL*Net from client

4  SQL*Net roundtrips to/from client

9  sorts (memory)

0  sorts (disk)

1  rows processed

---上面的执行计划结果说明merge into 比另一个写法更有效率?

HASH JOIN ANTI 和  HASH JOIN OUTER有什么区别?

另外,我想再问下,clear buffer 和 flush shared_pool 的区别?

还有我想再执行计划中看到物理读的次数,要用什么命令清除才能看到物理读的次数?

oracle数据库merge into,merge into 的用法相关推荐

  1. Oracle数据库中的instr函数的用法

    一.instr函数的用法 在Oracle中可以使用instr函数对某个字符串进行判断,判断其是否含有指定的字符.在一个字符串中查找指定的字符,返回被查找到的指定的字符的位置. 语法: instr(so ...

  2. criteria和oracle数据库使用,[原创]条件查找Criteria用法

    Criteria c = session.createCriteria(User.class); if(user.getUser_name() != null){ c.add(Restrictions ...

  3. oracle数据库中的update语句的用法

    测试   1.set一个字段 在表t_test中设置第二条记录(bs为2)的password为'***'. update t_test t     set t.password = '***'   w ...

  4. oracle中exist什么意思,oracle中not exists 是什么意思 , oracle数据库中exists的作用

    导航:网站首页 > oracle中not exists 是什么意思 , oracle数据库中exists的作用 oracle中not exists 是什么意思 , oracle数据库中exist ...

  5. ORACLE 10 g的 merge into 用法

    查看原文:http://www.ibloger.net/article/244.html 在Oracle 10g之前,merge语句支持匹配更新和不匹配插入2种简单的用法,在10g中Oracle对me ...

  6. Merge用法:Oracle 10g中对Merge语句的增强

    网址:  http://www.eygle.com/digest/2009/02/mergeoracle_10gmerge.html 在Oracle 10g之前,merge语句支持匹配更新和不匹配插入 ...

  7. Oracle数据库merge into的使用,存在则更新,不存在则插入

    1.在实际应用场景中,我们会用到:如果这条数据在表中,就更新数据:如果不存在这条数据,就插入这条数据. 在oracle中,可以使用merge into实现,在mysql中可以使用ON DUPLICAT ...

  8. Oracle数据库中SQL语句用法(一)

    Copyright © 2019 @Linyer. All Rights Reserved 下接Oracle数据库中SQL语句用法(二)[点击以查看] 目录 第1章:编写基本的SQL SELECT语句 ...

  9. mysql中merge的用法_mysql中merge表存儲引擎用法介紹

    mysql中merge表存儲引擎用法介紹: mysql的merge引擎類型允許你把許多結構相同的表合並為一個表.然后,你可以執行查詢,從多個表返回的結果就像從一個表返回的結果一樣.每一個合並的表必須有 ...

  10. Oracle数据库用法汇总

    一些Oracle数据库用法的小总结 1.使用insert into创建新表 insert into destdb.sub_contract (userid,contractid) select msi ...

最新文章

  1. 微信小程序图片自适应宽高比例显示解决方法
  2. 学习笔记 ACCESS 延迟注入
  3. python中关于操作时间的方法(一):使用time模块
  4. Atlas Samples Suse Linux 10.1
  5. 2015年各银行无抵押信用贷款利率及额度是多少?
  6. Quick Audience精准营销之后 良品铺子还将借力阿里云数据中台有更多动作
  7. springboot---request 中Parameter,Attribute区别
  8. 美团科技 Java工程师_美团Java工程师面试题(2018秋招)
  9. 无限流量手机怎样改服务器,无限流量手机服务器
  10. python项目结构目录结构_python 项目目录结构
  11. java去除以张开头的人名_写出java8实现对ListUser中的username字段过滤出不等于张三的数据...
  12. 中国大学MOOC-陈越、何钦铭-数据结构-习题解答-02 线性结构
  13. 基因编辑技术在农业中的应用综述
  14. git查看stash里面的具体内容
  15. Arcgis更换布局模板_PPT模板到底怎么用呢?
  16. 分享]基于Web开发资料专集
  17. 论混合软件架构的设计
  18. DB、DBS 和 DBMS 有什么区别
  19. 阿里云新Logo:生于代码
  20. Timer延时任务和ScheduledThreadPool执行延时任务

热门文章

  1. DeepLab InvalidArgumentError NodeDef mentions attr dilations not in Op name=Conv2D
  2. 近30所高校,获教育部点名表扬!
  3. 关于C语言的system函数用法
  4. Qt Quick实现的文件传输工具(TCP传输篇)
  5. 微博2面:微信朋友圈是怎么实现的?
  6. Mysql培训第一天
  7. 基于python的ansys_基于Python与ANSYS的达芬方程计算程序
  8. 大数据Hadoop入门教程 | (一)概论
  9. 人脸识别——FaceBook的DeepFace、Google的FaceNet、DeepID
  10. 论文阅读笔记《Anomaly Detection in Nanofibrous Materials by CNN-Based Self-Similarity》