为什么 Dapper 的批量插入比我预期的要慢很多?
咨询区
kenwarner:
我的项目中有一个批量插入的需求,我采用的是 Dapper 连接数据库,下面是我的代码。
var members = new List<Member>();
for (int i = 0; i < 50000; i++)
{members.Add(new Member(){Username = i.toString(),IsActive = true});
}using (var scope = new TransactionScope())
{connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);scope.Complete();
}
上面代码插入需要 20s,插入量大概 2500/s
,虽效果还行,但我在网上找的文章说可以做到 45k/s
,请问如何做到这么高的插入量?
回答区
Fredrik Ljung:
下面是我批量插入的最佳实践,可以实现 50k 条数据 4s 搞定。
SqlTransaction trans = connection.BeginTransaction();connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members, transaction: trans);trans.Commit();
CallumVass:
我实现了一个可批量插入的扩展方法,参考代码如下:
public static class DapperExtensions
{public static async Task BulkInsert<T>(this IDbConnection connection,string tableName,IReadOnlyCollection<T> items,Dictionary<string, Func<T, object>> dataFunc){const int MaxBatchSize = 1000;const int MaxParameterSize = 2000;var batchSize = Math.Min((int)Math.Ceiling((double)MaxParameterSize / dataFunc.Keys.Count), MaxBatchSize);var numberOfBatches = (int)Math.Ceiling((double)items.Count / batchSize);var columnNames = dataFunc.Keys;var insertSql = $"INSERT INTO {tableName} ({string.Join(", ", columnNames.Select(e => $"[{e}]"))}) VALUES ";var sqlToExecute = new List<Tuple<string, DynamicParameters>>();for (var i = 0; i < numberOfBatches; i++){var dataToInsert = items.Skip(i * batchSize).Take(batchSize);var valueSql = GetQueries(dataToInsert, dataFunc);sqlToExecute.Add(Tuple.Create($"{insertSql}{string.Join(", ", valueSql.Item1)}", valueSql.Item2));}foreach (var sql in sqlToExecute){await connection.ExecuteAsync(sql.Item1, sql.Item2, commandTimeout: int.MaxValue);}}private static Tuple<IEnumerable<string>, DynamicParameters> GetQueries<T>(IEnumerable<T> dataToInsert,Dictionary<string, Func<T, object>> dataFunc){var parameters = new DynamicParameters();return Tuple.Create(dataToInsert.Select(e => $"({string.Join(", ", GenerateQueryAndParameters(e, parameters, dataFunc))})"),parameters);}private static IEnumerable<string> GenerateQueryAndParameters<T>(T entity,DynamicParameters parameters,Dictionary<string, Func<T, object>> dataFunc){var paramTemplateFunc = new Func<Guid, string>(guid => $"@p{guid.ToString().Replace("-", "")}");var paramList = new List<string>();foreach (var key in dataFunc){var paramName = paramTemplateFunc(Guid.NewGuid());parameters.Add(paramName, key.Value(entity));paramList.Add(paramName);}return paramList;}
}
然后可以像下面这样使用。
await dbConnection.BulkInsert( "MySchemaName.MyTableName", myCollectionOfItems,new Dictionary<string, Func<MyObjectToInsert, object>>{{ "ColumnOne", u => u.ColumnOne },{ "ColumnTwo", u => u.ColumnTwo },...});
点评区
在实际开发中,批量插入是一个非常常见的场景,用 事务
和 拼sql
都是高效的方式,我在实际开发中,用的是事务方式
,学习了。
为什么 Dapper 的批量插入比我预期的要慢很多?相关推荐
- oracle怎样批量加字段,OCI方面的知识,哪位高手能帮忙修改下 想批量插入数据,且表的字段很多...
C/C++ code/************************* 编译语句 gcc -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I${ORACL ...
- ado.net mysql 批量插入_[Dapper].NET/C#程序开发中使用Dapper批量插入数据集合的方法应该如何实现?...
问题描述 使用Dapper如何向数据库中批量插入数据或者说使用Dapper如何插入一个集合(List),在没有使用Dapper(使用Ado.net)的情况下,我们通常的实现方式如下: try { co ...
- sql如何避免插入并发_SQL批量插入并发和性能注意事项
sql如何避免插入并发 One of the challenges we face when using SQL bulk insert from files flat can be concurre ...
- 个人用户永久免费,可自动升级版Excel插件,使用VSTO开发,Excel催化剂功能第11波-快速批量插入图片...
Excel自带插入图片功能,但操作步骤繁琐,插入图片后,还要一张张图片归位,插入的图片一般是用于可视化某些商品条码,增强阅读性.即一般会在商品条码旁边存放对应的图片,这些工作若用Excel自带的功能, ...
- Mybatis一对多、多对一、批量插入
在项目开发中,我们有遇到的对象关系通常是复杂的,每个对象并不是单独的.比如学生和老师之间关系,一个老师有多个学生,每个学生会对应一个老师(这里的老师主要是班主任),这种关系其实就是一对多的关系.Myb ...
- 批量插入数据SQL写法,批量处理数据
批量插入数据SQL写法,批量处理数据 今天在进行功能优化中遇到了碰到了一个功能,要处理10万条数据.在最开始开发时没有考虑那么多直接以单条数据来处理没有考虑到大批量数据的情况,导致功能不符合预期.那就 ...
- c mysql 批量插入_c#之mysql四种带事务批量插入
前言 对于像我这样的业务程序员开发一些表单内容是家常便饭的事情,说道表单 我们都避免不了多行内容的提交,多行内容保存,自然要用到数据库,如果循环打扰我数据库,数据库也会觉得很累,从而增加数据库服务器压 ...
- node mysql 批量写入_请问如何使用node.js在MySQL中进行批量插入
catspeake 我四处寻找关于批量插入对象的答案.Ragnar123的回答使我得出了这样的结论:function bulkInsert(connection, table, objectArray ...
- MySQL 批量插入:如何不插入重复数据?
以下文章来源方志朋的博客,回复"666"获面试宝典 知识这个东西,看来真的要温故而知新,一直不用,都要忘记了???? 业务很简单:需要批量插入一些数据,数据来源可能是其他数据库的表 ...
最新文章
- SSD框架训练自己的数据集
- Spring Boot知识清单
- 【原创】构建高性能ASP.NET站点 开篇
- Matlab英文操作系统下中文乱码的解决方案
- Java的中排序方式
- Hibernate主键生成策略与save()方法是否发sql语句的研究
- scheduled只执行一次,有个定时任务突然不执行了?
- windownavigatorscreenlocation
- 跳跃回溯____寻找最长平台
- Jquery ThickBox的使用
- matlab语法——min函数
- 小米笔记本触摸板失灵问题
- magisk安装失败_crDroid OS 安装刷入教程
- FPGA两片RAM的乒乓操作
- php如何配置gii,PHP Framework YII的里的gii设置。
- 华为路由器时间同步_好用实在价格亲民 - 华为路由WS5200四核版初体验
- android 一直开机画面,解决:Android模拟器一直停留在开机画面
- windows网络服务之配置网络负载均衡(NLB)群集
- arm服务器虚拟x86,x86服务器与arm
- Titanic:Machine Learning from Disaster 人工智能,大数据分析常用入门kaggle项目
热门文章
- xhprof php性能分析工具
- Silverlight中开发和设计人员的合作文档信息
- python ev3图形化编程软件下载_mPython(图形化编程软件)
- lstm数学推导_如何在训练LSTM的同时训练词向量?
- Apache 重写规则的常见应用 (rewrite)
- 2018-2019-2 20175235 实验四《Android开发基础》实验报告
- C#字符串、字节数组和内存流间的相互转换 - IT浪潮之巅
- IOS原生地图与高德地图
- 周报_2013第03周(2013/01/13-2013/01/19)
- C语言程序设计实验最短路径,7最短路径C语言程序设计.pdf