SqlServer数据插入性能小记
对于SQL性能,已经很久没关注了。由于近期项目既没有几千万的海量数据也没有过多的性能要求,所以在性能上也就没下太多功夫。然而,前不久和朋友闲谈间话题一转就说到程序上了,他说他用Delphi做了个数据导入的功能,插入数据的时候感觉很慢。以个人对SQL的了解,就建议他使用批量插入的方式,并很认真的告诉他这样应该会快很多。而在实际工作中,类似批量导入数据的功能是非常常见的,也许一个不小心我们就搞挂了服务器。那就究竟要怎么做才能给服务器留条活路,让用户不用点完上传看部电影再看上传结果呢?为此做了个小实验,并简单说下自己的看法。
环境:
CPU : i7;
内存 : 6G;
数据库:SqlServer2008;
数据量:10W
实验内容:
创建LoopInsert 和BatchInsert两个函数,LoopInsert中使用拼接的方式生成insert into xxx values(...) insert into xxx values(...) ...形式的sql执行并返回sql的执行时间,BatchInsert中同样使用拼接sql的方式生成insert into xxx values(...),(...),(...)形似的sql并返回sql的执行时间。利用控制台程序多次执行两个函数,并输出执行结果。
表结构:
CREATE TABLE TQRCode
(
ID INT PRIMARY KEY IDENTITY(1, 1) ,
Name NVARCHAR(300) ,
Remark NVARCHAR(300)
)
C#实现代码:
1 public class DataInertTest
2 {
3 /// <summary>
4 /// 循环插入
5 /// </summary>
6 /// <returns>执行时间(秒)</returns>
7 public double LoopInsert(int count)
8 {
9 StringBuilder sql = new StringBuilder();
10 for (int i = 0; i < count; i++)
11 {
12 sql.Append(" Insert into TQRCode(Name,Remark) values('这是第").Append(i).Append("条数据','这是第").Append(i).Append("条数据_remark') ");
13 }
14 //时间统计
15 var stopwatch = new Stopwatch();
16 stopwatch.Start();
17 new Helper().Excute(sql.ToString());
18 return stopwatch.Elapsed.TotalMilliseconds;
19 }
20
21 /// <summary>
22 /// 批量插入
23 /// </summary>
24 /// <returns>执行时间(秒)</returns>
25 public double BatchInsert(int count)
26 {
27 StringBuilder sql = new StringBuilder();
28 sql.Append(" Insert into TQRCode(Name,Remark) values ");
29 for (int i = 0; i < count; i++)
30 {
31
32 sql.Append(" ('这是第").Append(i).Append("条数据','这是第").Append(i).Append("条数据_remark') ");
33 if (i % 500 == 0)
34 {
35 sql.Append(" Insert into TQRCode(Name,Remark) values ");
36 }
37 else if (i < count - 1)
38 {
39 sql.Append(",");
40 }
41 }
42
43 //时间统计
44 var stopwatch = new Stopwatch();
45 stopwatch.Start();
46 new Helper().Excute(sql.ToString());
47 return stopwatch.Elapsed.TotalMilliseconds;
48 }
49 }
C#实现代码
注:sqlserver中单次批量插入数据最多1000条否则会提示我们:The number of row value expressions in the INSERT statement exceeds the maximum allowed number of 1000 row values.
测试代码:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 for (int i = 0; i < 3; i++)
6 {
7 var obj = new DataInertTest();
8 var t1 = obj.LoopInsert(100000);
9 var t2 = obj.BatchInsert(100000);
10
11 Console.WriteLine("LoopInsert : {0}", t1);
12 Console.WriteLine("BatchInsert : {0}", t2);
13 Console.WriteLine("--------------------------------------------------");
14
15 }
16 Console.ReadLine();
17 }
18 }
测试代码
测试结果:

执行了3次结果很明显,效率差距在10倍以上。批量插入的方式之所以比循环插入快,主要因为sqlserver中每个insert into 都是一个独立的事务,循环插入500条数据就是500个事务,而一次插入500条数据,就只有一个事务。事务减少了消耗自然也就小了。且频繁的事务提交相当影响数据库的性能,也就起到了影响整个系统性能的作用(嘿嘿,一不小心也许服务器就挂了)。
需要注意的是,测试中因为数据量不大所以两种方式都是采用的一次入库的方式,这样做可以减少数据库连接次数。但是这样做有个很大的弊端:内存消耗会很大。10w数据的sql拼接还好,如果是100w行那就未必了。所以,如果单条数据较大,建议每几百或几千行的时候提交一次,这个数字具体多大需要量体裁衣,平衡内存消耗。
SqlServer数据插入性能小记的更多相关文章
- 大数据应用之HBase数据插入性能优化实测教程
引言: 大家在使用HBase的过程中,总是面临性能优化的问题,本文从HBase客户端参数设置的角度,研究HBase客户端数据批量插入性能优化的问题.事实胜于雄辩,数据比理论更有说服力,基于此,作者设计 ...
- "Entity Framework数据插入性能追踪"读后总结
园友莱布尼茨写了一篇<Entity Framework数据插入性能追踪>的文章,我感觉不错,至少他提出了问题,写了出来,引起了大家的讨论,这就是一个氛围.读完文章+评论,于是我自己也写了个 ...
- python 读取SQLServer数据插入到MongoDB数据库中
# -*- coding: utf-8 -*-import pyodbcimport osimport csvimport pymongofrom pymongo import ASCENDING, ...
- .NET批量大数据插入性能分析及比较
数据插入使用了以下几种方式 1. 逐条数据插入2. 拼接sql语句批量插入3. 拼接sql语句并使用Transaction4. 拼接sql语句并使用SqlTransaction5. 使用DataAda ...
- 大数据应用之HBase数据插入性能优化之多线程并行插入测试案例
一.引言: 上篇文章提起关于HBase插入性能优化设计到的五个参数,从参数配置的角度给大家提供了一个性能测试环境的实验代码.根据网友的反馈,基于单线程的模式实现的数据插入毕竟有限.通过个人实测,在我的 ...
- .NET 百万级 大数据插入、更新 ,支持多种数据库
功能介绍 (需要版本5.0.44) 大数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现 当列越多转换越慢,SqlSugar将转换性能做到极致,并且采用数据库最佳API 操作数据库 ...
- c# 国内外ORM 框架 dapper efcore sqlsugar freesql hisql sqlserver数据常规插入测试性能对比
c# 国内外ORM 框架 dapper efcore sqlsugar freesql hisql sqlserver数据常规插入测试性能对比对比 在6.22 号发布了 c# sqlsugar,his ...
- SQLServer 批量插入数据的两种方法
SQLServer 批量插入数据的两种方法-发布:dxy 字体:[增加 减小] 类型:转载 在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Ins ...
- 一次EF批量插入多表数据的性能优化经历
距离上次的博客已经有15个多月了,感慨有些事情还是需要坚持,一旦停下来很有可能就会停很久或者从此再也不会坚持.但我个人一直还坚持认为属于技术狂热份子,且喜欢精益求精的那种.最近遇到两个和数据迁移相关的 ...
- SQL从入门到基础–03 SQLServer基础1(主键选择、数据插入、数据更新)
一.SQL语句入门 1. SQL语句是和DBMS“交谈”专用的语句,不同DBMS都认SQL语法. 2. SQL语句中字符串用单引号. 3. SQL语句中,对于SQL关键字大小写不敏感,对于字符串值大小 ...
随机推荐
- 我们有40%代码是 AI 写的
- context之WithTimeout的使用
1. context包的WithTimeout()函数接受一个 Context 和超时时间作为参数,返回其子Context和取消函数cancel2. 新创建协程中传入子Context做参数,且需监控子 ...
- jQuery.validator验证无效的可能原因
最近用jQuery.validator做表单的前端验证,却发现验证规则都无效.最后发现以下原因会导致校验无效 1.jquery.min.js重复引用. 2.js中有bug存在. 3.<input ...
- An Entry Example of Log4j
The log4j can be configured both programmatically and externally using special configuration files. ...
- 分布式系统架构1:共识算法Paxos
1.背景 今天开始更新分布式的文章,工作几年后还没系统的学习分布式的内容,趁着还有时间学习沉淀的时候多输出些文章 2.为什么需要分布式共识算法 思考:现在你有一份随时变动的数据,需要确保它正确存储在网 ...
- Qt 指定 so库 运行时路径
在Qt的pro文件最后添加运行时so库路径: QMAKE_RPATHDIR += /home/pi/qt5 注意,必须是绝对路径,相对路径无效(因为在pro文件中,相对路径是相对于项目路径)
- mysql忘记密码的终极解决方案(docker-compose)
MYSQL8的安全性能有所提高,装好后,各种不适应,需要各种调试. 1. 首先,root密码忘记或是更改,操作步骤: vi mysql/config/my.cnf 在[mysqld]的段中加上一句:s ...
- echarts 图表设置默认选中
echarts:https://echarts.apache.org/zh/api.html#events.legendselected tfjy1997:https://blog.csdn.net/ ...
- 使用 Azure AI Studio 构建和部署使用提示流的问答助驾系统
使用 Azure AI Studio 构建和部署使用提示流的问答助驾系统 See: Build and deploy a question and answer copilot with prompt ...
- Qt开发经验小技巧241-245
QString类是我个人认为Qt所有类中的精华,封装的无可挑剔.内置了各种进制数据的转换,比如将数据转成10进制.16进制显示,或者将10进制.16进制数据转成字符串显示.这里很容易忽略的一点就是,很 ...