MSSQL批量插入新方法,感觉效率蹭蹭往上涨,数据处理快多了
- 问答
- 2026-01-11 22:08:13
- 1
最近在处理一个项目,需要把几十万条数据从文件快速塞进SQL Server数据库里,以前的老办法就是写个循环,一条一条地INSERT,那个速度慢得啊,看着进度条都心急,后来琢磨了一下,发现了一个新方法,感觉效率真的是蹭蹭往涨,数据处理快多了,赶紧来分享一下。
这个方法的核心就是用一个叫做SqlBulkCopy的类,这个类好像是微软专门为这种大批量数据插入设计的,它不像普通的INSERT语句那样一次只处理一行,而是能把一整批数据一次性打包发给数据库服务器,让服务器自己去处理,这样一来,网络来回通信的次数就大大减少了,数据库那边也不用为每一条数据都分析一次执行计划、记录一次日志,负担小了很多,速度自然就上来了。
我记得这个方法是看了一个叫“博客园”的网站上一位技术博主的文章(来源:博客园 - 某技术博主文章《SQL Server 批量插入的几种方式对比》),里面详细比较了几种方法,SqlBulkCopy在性能上优势很明显,在微软官方的MSDN文档里(来源:微软MSDN文档 - SqlBulkCopy类)也找到了对这个类的详细说明,确认了它的可靠性。
具体怎么用呢?其实步骤不复杂,我用的是C#,所以下面用C#的例子来说明,你得把要插入的数据准备好,这些数据可能来自一个文本文件、一个Excel表格,或者是程序里动态生成的,不管来源是啥,你最终需要把它们整理成一个DataTable对象,或者是一个能实现IDataReader接口的对象。DataTable可能更直观一些,就像在内存里建了一个小表格,有列名,有行数据。

准备好数据表格之后,就可以创建SqlBulkCopy对象了,创建的时候需要传入你的数据库连接字符串或者已经打开的数据库连接,你要告诉它要把数据复制到哪个目标数据库的哪个表里,这是通过设置DestinationTableName属性来实现的。
SqlBulkCopy还有一些很实用的属性可以调整,让插入更高效。
BatchSize属性:这个可以设置每批发送多少行数据,虽然它叫“批量复制”,但如果你一下子上传几十万条,它内部可能还是会分成更小的批次来处理,你可以通过这个属性控制批次大小,比如设置成1000或5000,找到一个速度和内存占用的平衡点。NotifyAfter属性:这个挺有用的,如果你插入的数据量非常大,耗时比较长,总得让用户知道进度吧?设置这个属性后,比如设为10000,那么每成功插入10000行数据,SqlBulkCopy就会触发一个事件,你可以在事件处理程序里更新进度条,用户体验就好多了。BulkCopyTimeout属性:设置超时时间,避免因为数据量太大或者网络问题导致程序一直傻等。
如果源数据的列顺序和目标数据库表的列顺序不完全一样,你还可以通过ColumnMappings属性来手动映射一下,告诉它源数据的第一列对应目标表的哪个列,第二列对应哪个列,非常灵活。

都设置好了之后,最关键的一步就是调用WriteToServer方法,把你准备好的DataTable或者IDataReader传进去,你就可以去倒杯水,回来可能发现数据已经全部进去了,速度比之前一条条INSERT快了不是一星半点。
这个方法也不是说在所有场景下都是万能药,它最适合的就是这种单纯的、大量的数据插入,如果插入过程中还需要复杂的逻辑判断、关联查询或者数据转换,可能就需要结合其他方式了,但就我遇到的这种“灌数据”SqlBulkCopy绝对是首选。
我还试过另一种写法,就是先用SqlBulkCopy把数据快速插入到一个临时表里,这个临时表的结构和最终的目标表一样,但是不建索引,约束也少,这样插入速度能达到最快,等所有数据都进了临时表之后,再用一条SQL语句,从临时表INSERT到最终的目标表,在这条SQL语句里进行必要的去重、数据转换或者关联查询,这样就把耗时的操作分成了两步,第一步追求极速写入,第二步再利用数据库的能力进行精确处理,整体效率也非常高,这个方法是在一个叫“Code Project”的国外编程网站上看到的(来源:Code Project - 高性能数据导入策略)。
从这次经历来看,摆脱那种一条条插入的思维,采用这种批量操作的思想,对于提升数据处理效率来说至关重要。SqlBulkCopy这个工具用起来不复杂,但带来的性能提升是实实在在的,确实让我感觉效率蹭蹭往上涨,处理起大数据量来有底气多了,如果你也经常需要做类似的数据导入工作,强烈建议你试试这个方法。
本文由芮以莲于2026-01-11发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/78939.html
