SQL Server如何实现批量Upsert的高性能方案_利用Merge语句

阿浩君_7575

阿浩君_7575

2026-04-21

359人浏览

原创

sql server 的 merge 语句必须同时包含 when matched 和 when not matched 分支,禁止省略任一分支;需确保 using 子句返回结果集、on 条件避免 null 比较、批量操作使用临时表加索引、并发时添加 holdlock 提示,并严格满足目标表的 not null 约束。

sql server如何实现批量upsert的高性能方案_利用merge语句

MERGE 语句必须配对 WHEN MATCHED 和 WHEN NOT MATCHED

SQL Server 的 MERGE 不允许只写一半逻辑。哪怕你业务上「只更新不插入」或「只插入不更新」,也得显式写出两个分支,否则直接报错:The MERGE statement attempted to UPDATE or DELETE the same row more than once 或语法拒绝。常见错误是漏掉 WHEN NOT MATCHED,或把 INSERT 写成 INSERT INTO ... SELECT 却没加 VALUES 子句。

  • WHEN NOT MATCHED THEN INSERT (col1, col2) VALUES (s.col1, s.col2) —— 必须用 VALUES,不能省略
  • 源数据(USING 子句)必须返回结果集,USING (VALUES (@id, @name)) AS s(id, name) 合法,但裸写 USING (@id, @name) 会报错
  • ON 条件里避免 NULL 比较:例如 t.id = s.id 在任一为 NULL 时恒为 UNKNOWN,导致匹配失败;应提前过滤或改用 t.id = s.id OR (t.id IS NULL AND s.id IS NULL)(需确保业务允许空值主键)

批量 Upsert 必须走临时表 + 索引优化

单行循环执行 MERGE(比如 Python 中 for row in df: cursor.execute(...))在万级以上数据量下极慢,本质是网络往返 + 解析开销叠加。真正高性能的做法是:先把数据批量载入临时表,再用 MERGE 一次处理整个结果集。

  • 创建本地临时表:CREATE TABLE #staging (id INT, name NVARCHAR(50), url VARCHAR(200))
  • 用 bcp、SqlBulkCopy 或 pymssql 的 executemany 批量灌入数据(比逐行快 10–100 倍)
  • ON 字段必须有索引:目标表的匹配列(如 id)要是主键或唯一索引;临时表的对应列也建议建索引(尤其数据量 > 10k)
  • 避免在 ON 中写函数或表达式,例如 UPPER(t.email) = UPPER(s.email) 会让索引失效

并发安全要加 HOLDLOCK,别信默认隔离级别

Podwise
Podwise

Podwise是一款为播客听众提供转写、摘要、思维导图和知识管理的 AI 播客应用。

下载

高并发场景下,多个 MERGE 同时运行可能因幻读导致重复插入或丢失更新。SQL Server 默认的 READ COMMITTED 不足以保护 MERGE 的匹配判断过程。必须显式加锁提示。

  • 在目标表别名后加 WITH (HOLDLOCK),等价于 SERIALIZABLE,确保整个 MERGE 过程串行化
  • 错误写法:MERGE INTO users AS t USING ... —— 缺少锁提示,高并发时大概率出问题
  • 正确写法:MERGE INTO users WITH (HOLDLOCK) AS t USING ...
  • 注意:HOLDLOCK 会延长锁持有时间,若批量数据跨分钟级,要考虑阻塞影响

字段对齐和 NOT NULL 约束最容易被忽略

MERGE 的 INSERT 分支和 UPDATE 分支字段不要求顺序一致,但每个分支都必须满足目标表的约束。最常踩的坑是:目标表某列为 NOT NULL,而 INSERT 分支里没提供值,或传了 NULL,直接报错中断整个语句。

  • 检查目标表 DDL:SELECT COLUMN_NAME, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'your_table'
  • INSERT 分支必须显式列出所有 NOT NULL 列,并确保值非空(包括默认值列也要显式写,除非定义了 DEFAULT 且未禁用)
  • 如果源数据某些字段可能为空,INSERT 分支里用 ISNULL(s.col, 'default') 或 CASE 处理,别指望数据库自动补

真正卡性能的地方往往不是 MERGE 本身,而是 ON 条件能不能走索引、临时表有没有建好、并发时锁没加对——这些点没调好,再标准的语法也扛不住批量压力。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

4991

4

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2023.06.29

2485

3

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2023.08.14

3781

10

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

2023.08.31

2711

3

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.05

907

5

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.09

2427

5

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

2023.10.16

2427

4

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

2023.10.16

2813

3

vb连接数据库的方法
vb连接数据库的方法

vb连接数据库的方法有使用ADO对象库、使用OLEDB数据提供程序、使用ODBC数据源等。详细介绍:1、使用ADO对象库方法,ADO是一种用于访问数据库的COM组件,可以通过ADO连接数据库并执行SQL语句。可以使用ADODB.Connection对象来建立与数据库的连接,然后使用ADODB.Recordset对象来执行查询和操作数据;2、使用OLEDB数据提供程序方法等等。

2023.10.19

2241

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
零基础精通 PS 视频教程
零基础精通 PS 视频教程

共268课时 | 119.4万人学习

前端工程师必备技能—PS切图
前端工程师必备技能—PS切图

共11课时 | 2.2万人学习

麦子学院Photoshop切片视频教程
麦子学院Photoshop切片视频教程

共13课时 | 4.3万人学习