首页 > 数据库 >SQLServer中批量插入数据方式的性能对比

SQLServer中批量插入数据方式的性能对比

时间:2022-12-02 22:03:20浏览次数:62  
标签:方案 存储 批量 表值 -- 代码 SQLServer 插入


昨天下午快下班的时候,无意中听到公司两位同事在探讨批量向数据库插入数据的性能优化问题,顿时来了兴趣,把自己的想法向两位同事说了一下,于是有了本文。

公司技术背景:数据库访问类(xxx.DataBase.Dll)调用存储过程实现数据库的访问。

技术方案一:

压缩时间下程序员写出的第一个版本,仅仅为了完成任务,没有从程序上做任何优化,实现方式是利用数据库访问类调用存储过程,利用循环逐条插入。很明显,这种方式效率并不高,于是有了前面的两位同事讨论效率低的问题。

技术方案二:

由于是考虑到大数据量的批量插入,于是我想到了ADO.NET2.0的一个新的特性:SqlBulkCopy。有关这个的性能,很早之前我是亲自做过性能测试的,效率非常高。这也是我向公司同事推荐的技术方案。

技术方案三:

利用SQLServer2008的新特性--表值参数(Table-Valued Parameter)。表值参数是SQLServer2008才有的一个新特性,使用这个新特性,我们可以把一个表类型作为参数传递到函数或存储过程里。不过,它也有一个特点:表值参数在插入数目少于 1000 的行时具有很好的执行性能。

技术方案四:

对于单列字段,可以把要插入的数据进行字符串拼接,最后再在存储过程中拆分成数组,然后逐条插入。查了一下存储过程中参数的字符串的最大长度,然后除以字段的长度,算出一个值,很明显是可以满足要求的,只是这种方式跟第一种方式比起来,似乎没什么提高,因为原理都是一样的。

技术方案五:

考虑异步创建、消息队列等等。这种方案无论从设计上还是开发上,难度都是有的。

技术方案一肯定是要被否掉的了,剩下的就是在技术方案二跟技术方案三之间做一个抉择,鉴于公司目前的情况,技术方案四跟技术方案五就先不考虑了。

接下来,为了让大家对表值参数的创建跟调用有更感性的认识,我将写的更详细些,文章可能也会稍长些,不关注细节的朋友们可以选择跳跃式的阅读方式。

再说一下测试方案吧,测试总共分三组,一组是插入数量小于1000的,另外两组是插入数据量大于1000的(这里我们分别取10000跟1000000),每组测试又分10次,取平均值。怎么做都明白了,Let’s go!

1.创建表。

为了简单,表中只有一个字段,如下图所示:


2.创建表值参数类型

我们打开查询分析器,然后在查询分析器中执行下列代码:



​Create​​​ Type PassportTableType ​​as​​​ ​​Table​​​ ( PassportKey ​​​nvarchar​​(50) )



执行成功以后,我们打开企业管理器,按顺序依次展开下列节点--数据库、展开可编程性、类型、用户自定义表类型,就可以看到我们创建好的表值类型了如下图所示:


说明我们创建表值类型成功了。

3.编写存储过程

存储过程的代码为:


USE [TestInsert]

GO
/****** Object: StoredProcedure [dbo].[CreatePassportWithTVP] Script Date: 03/02/2010 00:14:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Kevin>
-- Create date: <2010-3-1>
-- Description: <创建通行证>
-- =============================================
Create PROCEDURE [dbo].[CreatePassportWithTVP]

@TVP PassportTableType readonly

AS
BEGIN
SET NOCOUNT ON;

Insert into Passport(PassportKey) select PassportKey from @TVP

END


可能在查询分析器中,智能提示会提示表值类型有问题,会出现红色下划线(见下图),不用理会,
继续运行我们的代码,完成存储过程的创建

4.编写代码调用存储过程。

三种数据库的插入方式代码如下,由于时间比较紧,代码可能不那么易读,特别代码我加了些注释。



主要部分的代码

标签:方案,存储,批量,表值,--,代码,SQLServer,插入
From: https://blog.51cto.com/u_11295556/5907612

相关文章

  • ASP.NET 向SQLSERVER中批量插入数据
    usingSystem.Data;usingSystem.Diagnostics;usingSystem.Data.SqlClient;stringconnectionString="DataSource=HG-J3EJJ9LSW5PY;InitialCatalog=Test......
  • C#中数据的批量插入和更新_Asp.net
    对于海量数据的插入和更新,ADO.NET确实不如JDBC做到好,JDBC有统一的模型来进行批操作.使用起来非常方便: PreparedStatementps=conn.prepareStatement("insertorupd......
  • SQLSERVER字符串函数
    1.ASCII返回字符表达式最左端字符的ASCII代码值。语法ASCII(character_expression)参数character_expression是类型为char或varchar的表达式。返回类型int示例下例......
  • golang的插入排序算法
    1、什么是插入排序?先看一个例子:{7,6,1,9,3}无序数列中,我们约定好无序数列的第一个元素7作为有序数列{7},然后分别对{6,1,9,3}的数与7进行比较移位得到新的有序数列。第一次迭......
  • MXD文件版本批量转换
    ArcGIS不同版本的mxd文件不兼容,例如我这里本地使用的是10.1的版本,无法打开10.5版本创建的mxd文件。如果是较少的mxd文件,可以通过在10.5版本的arcgis中打开,选择FILE—SAVEA......
  • 【问题】Unknown return value type: java.lang.Integer springboot插入数据 报错
    很诡异的事情发生了。。。。。。。在使用springboot搭建一个springboot整合mybatis的demo时,测试插入数据的方法,数据成功插入数据库了,但是控制台却报了这个错,提示为止返回类......
  • SpringBoot+ElasticSearch 实现模糊查询,批量CRUD,排序,分页,高亮!
    导入elasticsearch依赖创建高级客户端基本用法创建、判断存在、删除索引对文档的CRUD批量CRUD数据查询所有、模糊查询、分页查询、排序、高亮显示总结大致流程......
  • POI插入行,合并行的单元格
    1、POI插入行,合并行的单元格2、代码/** * *@Title:insertRow *@Description:TODO插入行 *@paramsheet *@paraminsertRowIndex *@Author:......
  • SQLServer常用近百条SQL语句(收藏版)
    1.sqlserver查看实例级别的信息,使用SERVERPROPERTY函数selectSERVERPROPERTY('propertyname')2.查看实例级别的某个参数XX的配置select*fromsys.configurations......
  • 使用post接口进行大批量导出文件
    在工作中,使用get方法导出文件会遇到一些问题:url长度限制,传入id量大且加载速度慢,所以抛弃以前的请求下载方式,使用post接口进行请求下载!  本次的导出文件为excel文件,其他......