因为.NET GC机质 一次操作太多数据库 GC就比较难回收,需要时间
如果分批操作 那么GC回收就会变快。
注意:分批能大大降低内存,不过执行效率可能变快,也可能变慢 ,合理占用内存有提升性能,相反内存太多也会降低性能
需要根据自已服务器的内存大小和服务器应用进行合理处理
可以减少内存开销,导出大的EXCEL等操作会用到
原理:比如一次将100万的集合在构造成成EXCEL那么你是操作100万的集合,而这种分批量处理你每次只是当操作几百条的集合
//用例1:底层SQL是每次读取200条 List<Order> order = new List<Order>(); db.Queryable<Order>().ForEach(it=> { order.Add(it); /*禁止这儿操作数据库因为会循环*/} ,200); //用例2:数据库导入实战 (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万的) //用例3:高性能转DTO (大数据千万不要用AutoMapper等工具性能很差) List<OrderDTO> order = new List<OrderDTO>(); db.Queryable<Order>().ForEach(it=> { order.Add(new OrderDTO(){ id=it.id ..... });} ,200); //用例4:分页取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一定单例,不然会有内存问题
比如启用了贪婪模式,一些低版本的.NET CORE应用比较常见
2016 © donet5.comApache Licence 2.0