insert/update/delete...returning 语句
insert/update/delete...returning 语句
在一些业务场景中,用户需要插入、更新、删除一行或者多行目标数据行,然后获得自己刚刚插入、更新、删除之后的行或者其部分字段的值,包括部分字段构成的任意合法的表达式的值。
对于 MySQL 用户来说,要做到这一点,用户通常需要在一个显式的事务中执行 update 语句,然后使用相同的查询条件把 update 的语句取出来。
之所以要在显式事务中做,是为了防止其他并发的事务 update 了本连接刚刚 update 的行,那样的话,随后的 select 语句得到行就不是本连接刚刚 update 之后的行了,因为这些行又被其他事务更新过了。
而在 Oracle 和 PostgreSQL 数据库中,用户可以使用 update/delete 语句的 returning 子句,用一条语句完成上述工作。
这样的好处是可以提升效率,省去的开销包括发送一条 select 语句以及做目标行的查找等工作;省去的开销还包括操作显式事务的开销,也就是发送 begin 和 commit 语句的开销。
因此,使用 update...returning 语句预期可以比在显式事务中 update 行,然后 select 出来,能够提升性能 10% 以上。
所以这是一个很好的功能。事实上如果你搜索 "mysql update returning",你还能搜到不少在 MySQL 中实现类似 oracle/postgresql 的单条 update/delete 语句的 returning 子句的文章,通过借助触发器和临时表等技巧和复杂的操作。
但是这些复杂的步骤导致语句执行效率也显著降低了,并且使用也不方便(需要对每个数据表创建触发器)。
为了提升用户的程序效率,降低用户的开发难度,提升用户使用 Klustron 的体验,我们在 Klustron 中也实现 insert/update/delete 语句的 returning 子句。
为此,我们在 Klustron-storage 中实现了 insert/update/delete... returning 语句供计算节点使用,并且在计算节点中基于 PostgreSQL 原有的 insert/update/delete...returning 语句的实现,加入了对远程数据读写的支持。
这样,Klustron 就具备了 insert...returning、update...returning 和 delete...returning 语句功能,分别返回 insert 语句插入的行,update 语句更新后的行,以及返回 delete 语句删除的行,包括这些行的字段组成的任意合法的表达式的值。用户已经可以在 Klustron 上使用这些功能。
下图展示了这个很 cool 的功能。
首先,建表并填充数据:
现在我们执行 update... returning 语句:
然后执行 delete... returning 子句:
最后,explain 一下 update/delete... returning子 句: