zoukankan      html  css  js  c++  java
  • Oracle Merge into中修改表的限制条件位置的区别

    Oracle Merge into中修改表的限制条件位置的区别

    前言

    版本:11.2.0.4.0

    说明:不讨论有insert子句的情况

    对于样例语句如下:

    merge into t1
    using t2
    on (t1.id = t2.id)
    when matched then
      update set t1.name = t2.name;

    想对t1做限制只更新t1.id=1的语句,那么下边3条SQL有什么区别:

    merge into (select * from t1 where t1.id=1) tt1  |  merge into t1                                  |  merge into t1
    using t2                                         |  using t2                                       |  using t2
    on (tt1.id = t2.id)                              |  on (t1.id = t2.id)                             |  on (t1.id = t2.id and t1.id=1)
    when matched then                                |  when matched then                              |  when matched then
      update set t1.name = t2.name;                  |    update set t1.name = t2.name where t1.id=1;  |    update set t1.name = t2.name;

    构造环境

    按照https://www.cnblogs.com/wangrui1587165/p/9844979.html里边的表做案例吧。

    create table student (stu_id varchar2(4),stu_name varchar2(4),sex varchar2(1),credit varchar2(2));
    insert into student values('0001','大王','2','88');
    insert into student values('0002','刘一','1','88');
    insert into student values('0003','陈二','2','66');
    insert into student values('0004','张三','0','66');
    
    
    create table student_temp (stu_id varchar2(4),stu_name varchar2(4),sex varchar2(1),credit varchar2(2));
    insert into student_temp values('0001','大王','2','77');
    insert into student_temp values('0002','刘一','1','77');
    commit;

    表数据如下:

    17:04:52 ZKM@zkm(413)> select * from student;
    
    STU_ID       STU_NAME     SEX CREDIT
    ------------ ------------ --- ------
    0001         大王         2   88
    0002         刘一         1   88
    0003         陈二         2   66
    0004         张三         0   66
    
    Elapsed: 00:00:00.00
    17:04:56 ZKM@zkm(413)> select * from student_temp;
    
    STU_ID       STU_NAME     SEX CREDIT
    ------------ ------------ --- ------
    0001         大王         2   77
    0002         刘一         1   77
    
    Elapsed: 00:00:00.00

    对如下三条语句做比对:

    1                                                                   2                                                               3
    merge into (select * from student_temp where stu_id = '0001') t1 | merge into student_temp t1 | merge into student_temp t1 using (select stu_id, stu_name, sex, credit from student) t2 | using (select stu_id, stu_name, sex, credit from student) t2 | using (select stu_id, stu_name, sex, credit from student) t2 on (t1.stu_id = t2.stu_id) | on (t1.stu_id = t2.stu_id) | on (t1.stu_id = t2.stu_id and t1.stu_id = '0001') when matched then | when matched then | when matched then update set t1.credit = t2.credit ; | update set t1.credit = t2.credit where t1.stu_id = '0001'; | update set t1.credit = t2.credit;

    执行计划和执行后表student_temp数据结果如下:

    1.

    16:01:46 ZKM@zkm(392)> select * from student_temp;
    
    STU_ID       STU_NAME     SEX CREDIT
    ------------ ------------ --- ------
    0001         大王         2   88
    0002         刘一         1   77

    -------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem | -------------------------------------------------------------------------------------------------------------------------- | 0 | MERGE STATEMENT | | 1 | | 0 |00:00:00.01 | 16 | | | | | 1 | MERGE | STUDENT_TEMP | 1 | | 0 |00:00:00.01 | 16 | | | | | 2 | VIEW | | 1 | | 1 |00:00:00.01 | 14 | | | | |* 3 | HASH JOIN | | 1 | 1 | 1 |00:00:00.01 | 14 | 1421K| 1421K| 695K (0)| |* 4 | TABLE ACCESS FULL| STUDENT | 1 | 1 | 1 |00:00:00.01 | 7 | | | | |* 5 | TABLE ACCESS FULL| STUDENT_TEMP | 1 | 1 | 1 |00:00:00.01 | 7 | | | | -------------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("STUDENT_TEMP"."STU_ID"="STU_ID") 4 - filter("STU_ID"='0001') 5 - filter("STU_ID"='0001')

    2.

    16:02:24 ZKM@zkm(392)> select * from student_temp;
    
    STU_ID       STU_NAME     SEX CREDIT
    ------------ ------------ --- ------
    0001         大王         2   88
    0002         刘一         1   77
    --------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation            | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    --------------------------------------------------------------------------------------------------------------------------
    |   0 | MERGE STATEMENT      |              |      1 |        |      0 |00:00:00.01 |      16 |       |       |          |
    |   1 |  MERGE               | STUDENT_TEMP |      1 |        |      0 |00:00:00.01 |      16 |       |       |          |
    |   2 |   VIEW               |              |      1 |        |      2 |00:00:00.01 |      14 |       |       |          |
    |*  3 |    HASH JOIN         |              |      1 |      2 |      2 |00:00:00.01 |      14 |  1185K|  1185K|  795K (0)|
    |   4 |     TABLE ACCESS FULL| STUDENT_TEMP |      1 |      2 |      2 |00:00:00.01 |       7 |       |       |          |
    |   5 |     TABLE ACCESS FULL| STUDENT      |      1 |      4 |      4 |00:00:00.01 |       7 |       |       |          |
    --------------------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - access("T1"."STU_ID"="STU_ID")

    3.

    16:03:05 ZKM@zkm(392)> select * from student_temp;
    
    STU_ID       STU_NAME     SEX CREDIT
    ------------ ------------ --- ------
    0001         大王         2   88
    0002         刘一         1   77
    --------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation            | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
    --------------------------------------------------------------------------------------------------------------------------
    |   0 | MERGE STATEMENT      |              |      1 |        |      0 |00:00:00.01 |      16 |       |       |          |
    |   1 |  MERGE               | STUDENT_TEMP |      1 |        |      0 |00:00:00.01 |      16 |       |       |          |
    |   2 |   VIEW               |              |      1 |        |      1 |00:00:00.01 |      14 |       |       |          |
    |*  3 |    HASH JOIN         |              |      1 |      1 |      1 |00:00:00.01 |      14 |  1421K|  1421K|  695K (0)|
    |*  4 |     TABLE ACCESS FULL| STUDENT      |      1 |      1 |      1 |00:00:00.01 |       7 |       |       |          |
    |*  5 |     TABLE ACCESS FULL| STUDENT_TEMP |      1 |      1 |      1 |00:00:00.01 |       7 |       |       |          |
    --------------------------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - access("T1"."STU_ID"="STU_ID")
       4 - filter("STU_ID"='0001')
       5 - filter("T1"."STU_ID"='0001')

    对于结果,可以得到:

    1                                                                   2                                                               3
    merge into (select * from student_temp where stu_id = '0001') t1 |  merge into student_temp t1                                    | merge into student_temp t1
    using (select stu_id, stu_name, sex, credit from student) t2     |  using (select stu_id, stu_name, sex, credit from student) t2  | using (select stu_id, stu_name, sex, credit from student) t2
    on (t1.stu_id = t2.stu_id)                                       |  on (t1.stu_id = t2.stu_id)                                    | on (t1.stu_id = t2.stu_id and t1.stu_id = '0001')
    when matched then                                                |  when matched then                                             | when matched then
      update set t1.credit = t2.credit ;                             |    update set t1.credit = t2.credit where t1.stu_id = '0001';  |   update set t1.credit = t2.credit;

    执行结果均相同,若是HASH JOIN前提下,对于第2条语句消耗的内存更多,这是因为第2条在id4和id5处没有对student和student_temp表先做过滤。而第1条和第3条则一样的性能

    建议使用第1种写法。原因是第3种写法从理解上看没有第一种好理解。

    而且如果在when not matched when insert子句下,意义就完全不一样了,参考https://www.cnblogs.com/wangrui1587165/p/9844979.html

    参考

    https://www.cnblogs.com/wangrui1587165/p/9844979.html

    ORACLE sql merge into update where条件位置与性能消耗

  • 相关阅读:
    java笔记之连接数据库
    关于数据集合的使用
    ubuntu下安装MySql
    Android笔记之Broadcast广播机制
    InputStream
    Android笔记之Toast
    jqGrid 复选框实现单选
    layer弹出框包含页面
    input不显示边框
    UUID
  • 原文地址:https://www.cnblogs.com/PiscesCanon/p/14422368.html
Copyright © 2011-2022 走看看