SQL Server中Upsert的三种方式(转载)

news/2024/11/17 16:17:46/文章来源:https://www.cnblogs.com/OpenCoder/p/18303994

本文介绍了SQL Server中Upsert的三种常见写法以及他们的性能比较。
SQL Server并不支持原生的Upsert语句,通常使用组合语句实现upsert功能。

 

假设有表table_A,各字段如下所示:

int型Id为主键。

 

方法1:先查询,根据查询结果判断使用insert或者update

IF EXISTS (SELECT 1 FROM table_A WHERE Id = @Id)BEGINUPDATE dbo.table_ASET Value = @ValueWHERE Id = @Id;END
ELSEBEGININSERT INTO dbo.table_A (Id, Value)VALUES(@Id, @Value)END

 

方法2:先更新,根据更新结果影响的条目数判断是否需要插入

UPDATE dbo.table_A
SET Value = @Value
WHERE Id = @Id;IF(@@ROWCOUNT = 0)
BEGININSERT INTO dbo.table_A (Id, Value)VALUES(@Id, @Value)
END

 

方法3:使用MERGE语句,将待upsert的数据作为source,merge到目标表 

MERGE INTO table_A as T
USING (SELECT @Id AS id, @Value AS value ) AS S
ON T.Id = S.id
WHEN MATCHED THENUPDATE SET T.Value = S.value
WHEN NOT MATCHED THENINSERT(Id, Value) VALUES(S.id, S.value);

 

性能比较
在50万行数据项中随机upsert10万次

 

场景一:upsert数据项100%命中update

 

 

场景二:upsert数据项100%命中insert

 

场景三:upsert数据项Id为随机数,~50%insert,~50%update

 

从图中可以看出实验数据存在部分偏差,大体上这三种方法在性能上的差别非常小。对于绝大多数upsert并非关键路径的程序,方法2在可读性和执行性能上综合来讲是较优的方案。
在对性能苛求的场景,可以选用MERGE语句,以下是MERGE语句的优点:”
Faster performance. The Engine needs to parse, compile, and execute only one query instead of three (and no temporary variable to hold the key).
Neater and simpler T-SQL code (after you get proficient in MERGE).
No need for explicit BEGIN TRANSACTION/COMMIT. MERGE is a single statement and is executed in one implicit transaction.
Greater functionality. MERGE can delete rows that are not matched by source (SRC table above). For example, we can delete row 1 from A_Table because its Data column does not match Search_Col in the SRC table. There is also a way to return inserted/deleted values using the OUTPUT clause.“

关于SQL Server的Merge介绍可以查看这里

 

原文链接

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/744318.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024/7/15 模拟赛 记录

noip NOI plus!几乎全员爆蛋( 本来能拿T1 20pts 暴力分的,但是居然CE了!!! max里两个参数,一个int一个longlong dev居然没报!!!光荣爆蛋(我估计是全场唯一一个没过编的:( 题解已存至网盘 https://fzoishare.xndxfz.com:7123/

[考试记录] 2024.7.15 csp-s模拟赛4

2024.7.15 csp-s模拟赛4 T1 传送带 题面翻译 有一个长度为 \(n\) 的一维网格。网格的第 \(i\) 个单元格包含字符 \(s_i\) ,是“<”或“>”。当弹球放在其中一个格子上时,它会按照以下规则移动: 如果弹球位于第 \(i\) 个格子上且 \(s_i\) 为 <,则弹球在下一秒会向左…

图论连通性

【学习笔记】图论连通性啊啊啊啊啊! 先引用一篇犇的:))) 缩点 弱连通: 对于有向图中两点 \(x\) 和 \(y\),它们在所有边为无向时存在一个环使它们相连。 强连通: 对于有向图中两点 \(x\) 和 \(y\),存在一个环使它们相连。 强连通子图: 对于有向图 \(G = (V, E)\),如果…

CS144 2024 winter 作业笔记

CS144 2024 winter 作业笔记 cs144 homework notes Created: 2024-05-14T10:24+08:00 Published: 2024-07-15T20:16+08:00 Categories: ComputerNetwork 目录checkpoint0配环境wegetreliable byte stream疑问checkpoint1checkpoint2bugs:checkpoint3model of input_Sendertimer…

解锁网络无限可能:揭秘微软工程师力作——付费代理IP池深度改造与实战部署指南

"揭秘微软工程师力作:付费代理IP池深度改造,四大模块精讲,含实战部署指南。掌握高效、稳定代理IP资源,解锁网络无限可能。从筛选管理到安全加密,详细步骤助您快速搭建专属代理网络。尊享付费阅读,获取深度技术洞察与实践指导。"基于付费代理的代理IP池 项目来源…

SpringIOC 容器

SpringIOC 容器 一、组件的概念 什么是组件? 常规的三层架构处理请求流程:划分为组件后:组件就是所有可以重用的java对象,组件一定是对象,对象不一定是组件二、Spring 进行组件管理 Spring框架替代了程序员原有的new对象和对象属性赋值的动作组件对象实例化组件属性赋值组…

javap和字节码

javap字节码的基本信息public class Test {private int age = 10;public int getAge() {return age;} }在 class 文件的同级目录下输入命令 javap -v -p Test.class 来查看一下输出的内容// 字节码文件的位置 Classfile /D:/Code/code/JavaCode/JavaSourceLearn/out/production…

Prometheus之钉钉

要实现Prometheus通过Alertmanager发送告警到钉钉,您可以按照以下步骤进行配置:创建钉钉机器人:首先,您需要在钉钉群中添加一个自定义机器人,并获取机器人的Webhook地址。创建机器人时,您可以设置安全验证方式,如加签。创建完成后,保存好Webhook地址和加签后的秘钥(如…

Java——N以内累加求和

2024/07/15 1.题目 2.错误 3.分析 4.答案 1.题目2.错误 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int N = scanner.nextInt();int sum = 0;while (N<=1000) {for (int i=1;i<=N;…

SQLCoder部署和应用

SQLCoder文生SQL部署和应用主页个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/SQLCoder简介 SQLCoder是一个用于生成SQL语句的工具,可以通过输入自然语言描述的需求,生成对应的SQL语句。SQLCoder支持连接数据库,对生成的SQL语句可…

NOIP 十三连测 #2 补题

逆天输出文件 .ans reverse 水题,随便自己造两组数据都能看出规律: \[\begin{cases}a_n a_{n - 2} \dots a_1 + a_2 a_4 \dots a_{n - 1}(n \mod 2 = 1) \\ a_n a_{n - 2} \dots a_2 + a_1 a_3 \dots a_{n - 1 } (n \mod 2 = 0)\end{cases} \]logistics 先求出最小生成树的 \…

MySQL时间戳转成日期格式

将时间戳转换为日期格式:-- 如果时间戳为毫秒级长度为13位,需要先除以1000 SELECT id, `task_name` ,FROM_UNIXTIME(`task_register_begin_time`/1000,%Y-%m-%d %H:%i:%s) as task_register_begin_time,FROM_UNIXTIME(`task_register_end_time`/1000,%Y-%m-%d %H:%i:%s) as t…