SQL SERVER中使用Merge进行批量操作

在.net开发过程中,经常会和数据库打交道。微软的产品包里,SQL SERVER便是一个强大的数据库管理系统(DBS)。我们编写的.net程序怎么和DBS进行交互呢?笔者最常用的便是ado.net组件,其中包括了执行sql命令,执行存储过程等丰富的操作方法。在ERP(企业资源计划)系统中,最常见的场景便是单条数据的增、删、改,或者小批量的DML(数据操纵语言)操作。在这种场景下,应用程序和DBS的交互延迟是很少被关注的(注意:ERP系统中的查询效率往往是开发过程中的优化重点)。但是,在一个频繁执行DML操作的系统中,交互延迟就成为了影响整体性能的一个关键点。

比如,某个处理过程接收一个体积较大的输入,经过内部逻辑运算后,产出几个体积较大的输出,最后要将输出结果保存到数据库中。假设完成一条Insert命令需要10ms,200条数据就需要2s,2000条数据就需要20s。如果程序中其他功能的执行时间总和为5s,那么此处的20s就是个祸害。怎样缩短这个时间呢?.net里提供了SqlBulkCopy类型,支持将一个数据集以批量的方式快速插入到数据库中。20s可以变成200ms,效果是明显的,局限也是明显的。纯插入操作场景是很少的,插入和更新并行场景是更加常见的。这时我们就会希望.net,或者DBS为我们提供一个“无则插入,有则更新”的功能。

MySQL数据库管理系统就提供了这个实用的功能,不过SQL SERVER中没有这个功能,那怎么办呢?

一条道走到黑不行了,我们可以曲线救国。SQL SERVER 2008中添加了Merge关键字,其详细语法此处不再列出,功能就是对两张表进行合并操作。我们可以指定匹配规则,两条记录匹配的时候可以定义更新或者删除操作,不匹配时定义插入或者删除操作。仔细一想,这就包含了“无则插入,有则更新”。接下来就是具体如何实现了。

笔者的实现思路如下:在应用程序中,将结果集缓存起来,然后使用SqlBulkCopy批量插入到一张副表,接下来调用存储过程执行Merge操作将副表数据合并到主表,最后清空副表。两个过程的速度都是很快的,所以整体性能也很可观。唯一麻烦的就是,必须为目标表建立一张副表。不过副表会被不断清空,不占用存储空间,所以还是值得使用的。

Merge的语法层面的限制较多,笔者研究的不是很深入,欢迎发表不同观点。

你可能感兴趣的:(编程语言-SQL)