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关键字大小写不敏感,对于字符串值大小 ...
随机推荐
- chcapter 2 量子力学介绍
2.4.3 约化密度矩阵 对于A,B 构成的两体系统,A的约化密度矩阵可通过对系统B partial trace: 具体的操作为:首先把 AB 密度矩阵写成所有 ' 基矩阵叠加' 的展开形式,即每一 ...
- yum 安装软件出现 gpg keys 相关问题
问题:Public key for *.rpm is not installed 系统中没有能验证该 RPM 数字签名的公钥 安装现有的 gpg 公钥,在 /etc/pki/rpm-gpg/ 下,可以 ...
- 21.Kubernetes配置默认存储类
Kubernetes配置默认存储类 前言 今天在配置Kubesphere的时候,出现了下面的错误 经过排查,发现是这个原因 我通过下面命令,查看Kubernetes集群中的默认存储类 kubectl ...
- 【Playwright + Python】系列(十)利用 Playwright 完美处理 Dialogs 对话框
哈喽,大家好,我是六哥!今天我来给大家分享一下如何使用playwight处理Dialogs对话框,面向对象为功能测试及零基础小白,这里我尽量用大白话的方式举例讲解,力求所有人都能看懂,建议大家先**收 ...
- NOIP2023模拟9联测30 T3 高爸
NOIP2023模拟9联测30 T3 高爸 三分啊,三分-- 思路 设现在的平均力量值为 \(x\),大于 \(x\) 力量值的龙有 \(n\) 条,小于等于的龙有 \(m\) 条,花费为: \[a( ...
- 3、oracle内存讲解
oracle数据库实例(instance) 数据库打开以后,会生成一个内存结构和一堆进程 内存和进程:就是oracle的实例instance oracle数据库实例结构: 用户是通过连接实例来访问数据 ...
- apache tomcat 6集群负载和session复制
无意间看到tomcat 6集群的内容,就尝试配置了一下,还是遇到很多问题,特此记录.apache服务器和tomcat的连接方法其实有三种:JK.http_proxy和ajp_proxy.本文主要介绍最 ...
- C语言八股文(温故知新)
1.volatile关键字 volatile int i=10; int j = i; ... int k = i; volatile告诉编译器i变量是随时可能发生变化的,例如IO端口的输入值,所以每 ...
- 理解Flink之四State
在Flink的官网写着:Stateful Computations over Data Streams. 基于状态计算的数据流. 在流式计算中,希望做一些聚合分析等.那么就需要保存当前日志的状态,以备 ...
- Chrome浏览器本地安装插件
前情 Chrome是目前世面上很受欢迎的浏览器,你可以通过它的插件扩展功能安装插件优化使用体验和增加功能. 坑位 对于国内受墙影响的用户无法直接通过应用商店安装插件,通过离线安装插件会发现浏览器会提示 ...