语法

MERGE INTO target
USING source
ON source.a = target.a
WHEN MATCHED THEN
UPDATE SET a = source.a, b = source.b, c = source.c
WHEN NOT MATCHED THEN
INSERT (a, b, c) values (a, b, c)

merge into 实际上是一个语法糖, 相对应的语义也可以通过其他的 sql 语法来表达, 例如 UPDATE/DELETE/INSERT, 但是 merge into 的好处是本身一次事务, 因此可以原子性的完成多个修改的操作.

databricks merge into

Paimon merge into

在 Paimon 中, 主键表和非主键表提供了不同的 merge into 实现方式.

非主键表

COW

处理流程

  1. 通过 join 找出 update/delete 语句所涉及的文件, 及 touched splits. 这一步不需要读取源表的全量字段数据, 只需要读取关联条件所涉及的字段
  2. 将所有涉及到的数据文件作为数据源读取, 并和 source 表进行 full outer join, 对 join 结果进行 match 和 not match 的处理, 并写出至新文件中
  3. 将所有的老的数据文件标记为删除文件, 新写入生成的文件标记为新增文件

为什么需要第一次 inner join?

当 Matched Action 中涉及对原始文件的修改需求, 例如 merge action 中存在 UPDATE 或 DELETE 子句时, 就有两种方式

  • 对 target 表进行一次 insert overwrite, 那么这样对于涉及 update/delete 的文件自然就完成了更新
  • 通过 inner join 找出涉及修改的文件, 再修改完成后通过指定文件 DELETE 的方式标记删除

显然, 在小范围更新的场景下, 第二种方式会更加合适, 可以减少重写文件的数量, 降低存储放大.

为什么需要将 non touched splits 也纳入到计算中?

因为有 WHEN NOT MATCHED 这类 not matched by source/target 时, 就需要将 inner join 未匹配上的数据也参与计算才能使得 WHEN NOT MATCHED 条件判断准确.

劣势:

  1. 原来的一次 join 操作, 被转化为两次 join
  2. 如果 source 是一个包含计算逻辑的 view, 也会被展开执行

优势:

  1. 如果 touched 列表比较小, 可以降低过程中重写的开销以及存储空间

Deletion vector

  1. 直接基于原始的 target, source 进行 full outer join, 同时读取的时候会读取出 target 表中的 row_index, 用于后续的标记删除
  2. 基于 merge action 进行处理
    • 将 INSERT 和 UPDATE_AFTER 数据写入 add 新增文件
    • 将其中的 DELETE 数据标记删除, 构建成 deletion vector 索引文件

优势

  1. 只有一轮 join 和原始计算开销相近
  2. 通过标记删除的方式, 同样可以降低存储空间

主键表

主键表的流程和上面的流程其实很像, 因为本身主键表就有更新删除能力, 因此构建出变更行后直接写回主键表即可.

参考

Paimon merge into 实现原理的更多相关文章

  1. 排序合并连接(sort merge join)的原理

    排序合并连接(sort merge join)的原理 排序合并连接(sort merge join)的原理     排序合并连接(sort merge join)       访问次数:两张表都只会访 ...

  2. Log Structured Merge Trees(LSM) 原理

    http://www.open-open.com/lib/view/open1424916275249.html

  3. 《oracle每天一练》Merge Into 语句代替Insert/Update在Oracle中的应用实战

    转载自窃破天道 动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明: 在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也 ...

  4. 使用Merge Into 语句实现 Insert/Update

    网址: http://www.eygle.com/digest/2009/01/merge_into_insertupdate.html 动机: 想在Oracle中用一条SQL语句直接进行Insert ...

  5. Oracle中merge into的使用

    http://blog.csdn.net/yuzhic/article/details/1896878 http://blog.csdn.net/macle2010/article/details/5 ...

  6. oracle merge用法

    动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明: 在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也就是说当存在记录 ...

  7. Oracle中merge into的使用 (转)

    该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据. ORACLE 9i 中,使用此命令必须同时指定UPDATE 和INSERT 关键词,ORACLE 10g 做了如下改动. 1.ins ...

  8. Oracle中merge into的使用 (转)

    http://blog.csdn.net/yuzhic/article/details/1896878 http://blog.csdn.net/macle2010/article/details/5 ...

  9. 浅谈SQL Server中的三种物理连接操作(HASH JOIN MERGE JOIN NESTED LOOP)

    简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge J ...

  10. 关系型数据库工作原理-归并排序(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

随机推荐

  1. Java调用Shell问题整理

    背景 java可以通过Runtime来调用其他进程,如cmd命令,shell文件或脚本等. 基本用法 Runtime执行时返回一个Process对象,利用该对象完成脚本执行.下面的例子中,Linux的 ...

  2. Python+Selenium模拟人工抓取数据

    Selenium 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Fire ...

  3. 使用Visual Studio Code进行前端开发并运行前端页面时提示:npm WARN Local package.json exists, but node_modules missing, did you mean to install?

    使用Visual Studio Code进行前端开发并运行前端页面时提示如下错误: npm WARN Local package.json exists, but node_modules missi ...

  4. 史上最通俗Netty入门长文:基本介绍、环境搭建、动手实战

    原作者江成军,原题"还在被Java NIO虐?该试试Netty了",收录时有修订和改动. 1.阅读对象 本文适合对Netty一无所知的Java NIO网络编程新手阅读,为了做到这一 ...

  5. Windows应用开发-常用工具集推荐

     .NET/WPF开发 Visual Studio 最新版本是VS2022,官网下载:Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 VsColorOutput 控制台 ...

  6. CF div2 996(A~D)

    手速场,前三题偏简单,后三题偏难.赛时三题,C题做法麻烦了些导致过得不是很快,但最后打得也不是很差. A 两只青蛙相邻时,可移动的青蛙一定输:直接把该青蛙挤到边缘即可. 而是否相邻可以直接用二者初始间 ...

  7. python基础学习6和7

    模块类与对象 模块 内置模块 time, random, os, json 第三方模块 requests, pandas, numpy,.... 自定义模块 xxx.py 常见的内置模块 hashli ...

  8. java基础知识回顾之java Thread类学习(三)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

    1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...

  9. 从Linux零拷贝深入了解I/O

    转载&学习文章:从Linux零拷贝深入了解I/O 本文将从文件传输场景以及零拷贝技术深究 Linux I/O 的发展过程.优化手段以及实际应用. 前言 存储器是计算机的核心部件之一,在完全理想 ...

  10. Kevin pg walkthrough Easy

    第二个window 靶机 尝试访问 80 web界面 然后是个登录界面 我尝试admin admin 登录成功 发现版本 发现了exp https://www.exploit-db.com/explo ...