因为.NET GC机质 一次操作太多数据库 GC就比较难回收,需要时间
如果分批操作 那么GC回收就会变快。
注意:分批能大大降低内存,不过执行效率可能变快,也可能变慢 ,合理占用内存有提升性能,相反内存太多也会降低性能
需要根据自已服务器的内存大小和服务器应用进行合理处理
可以减少内存开销,导出大的EXCEL等操作会用到
原理:比如一次将100万的集合在构造成成EXCEL那么你是操作100万的集合,而这种分批量处理你每次只是当操作几百条的集合
//底层SQL是每次读取200条
List<Order> order = new List<Order>();
db.Queryable<Order>().ForEach(it=> { order.Add(it); /*禁止这儿操作数据库因为会循环*/} ,200);
//用例1:数据库导入实战 (db的Order表导入到db2的Order表)
var pageList = new List<Order>();
var pageSize=200000;//每次读取20万 (数据库是1-20万 20万-40万这样读取)
db.Queryable<Order>().ForEach(it =>{
pageList.Add(it);
if (pageList.Count==pageSize) //每个分页的最一次执行,防止循操作库
{
db2.Fastest<Order>().BulkCopy(pageList);//插入分批数据
pageList = new List<Order>();//清空
}
},pageSize);//设置分页
db2.Fastest<Order>().BulkCopy(pageList);//插入剩余的 (最后一页可能有不足20万的)
//用例2:高性能转DTO (大数据千万不要用AutoMapper等工具性能很差)
List<OrderDTO> order = new List<OrderDTO>();
db.Queryable<Order>().ForEach(it=> { order.Add(new OrderDTO(){ id=it.id ..... });} ,200);
//用例3:分页取10000条,底层SQL是200一次读出来
int count = 0;
db.Queryable<Order>().ForEachByPage(it=>{order.Add(it);/*禁止这里写数据库访问操作*/},1,10000,ref count, 200);
//想明白原理最好结合AOP去看SQL需要升级到: SqlSugarCore 5.1.4.149-preview23+
List<Order> order = new List<Order>();
db.Queryable<UserInfo001>().ForEachDataReader(it => {
order.Add(it);//原理是DataReader的回调函数
});你们业务中如果需要将List进行分页操作就可以用这个函数
db.Utilities.PageEach(allList, 100 ,pageList=> {
//pageList每次只有100条
});
//异步用 PageEachAsync
await db.Utilities.PageEachAsync(allList, 100, async pageList => { //要加await
await db.Insertable(pageList).ExecuteCommandAsync();//要加await
});使用UseParameter 底层会分页处理大大降低内存,当然插入时间可能变长不同库机质不同
await db.Insertable(pageList).UseParameter().ExecuteCommand(); await db.Insertable(pageList).PageSize(100).ExecuteCommand();
有自带分批函数
//如果数据库现有数据比较多出现比较慢,这个时候可以试试分页 db.Fastest<Order>().PageSize(300000).BulkCopy(insertObjs);
如果用了SqlSugarScope一定单例,不然会有内存问题
2016 © donet5.comApache Licence 2.0