海量数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现
当列越多转换越慢,SqlSugar将转换性能做到极致,并且采用数据库最佳API
操作数据库达到极限性能
大数据插入
db.Fastest<Order>().BulkCopy(lstData);//插入 db.Fastest<Order>().PageSize(100000).BulkCopy(insertObjs); db.Fastest<System.Data.DataTable>().AS("order").BulkCopy(dataTable); //使用Winfom需要看标题2
大数据更新
db.Fastest<Order>().BulkUpdate(GetList())//更新 db.Fastest<Order>().PageSize(100000).BulkUpdate(GetList())//更新 db.Fastest<Order>().BulkUpdate(GetList(),new string[] { "Id"});//无主键 db.Fastest<Order>().BulkUpdate(GetList(), new string[]{"id"}, new string[]{"name","time"})//只更新几列 //DataTable db.Fastest<System.Data.DataTable>().AS("Order").BulkUpdate(dataTable,new string[] {"Id"});//Id是主键 db.Fastest<System.Data.DataTable>().AS("Order").BulkUpdate(dataTable,new string[] {"Id"},更新的列); //使用Winfom需要看标题2
大数据 : 插入或者更新
//原理 //Oracle和SqlServer使用了Merge Into+BulkCopy //其他库底层是 db.Storageable(list).ExecuteSqlBulkCopy() db.Fastest<Order>().BulkMerge(List); db.Fastest<Order>().PageSize(100000).BulkMerge(List); //DataTable 升级到:SqlSugarCore 5.1.4.147-preview15+ db.Fastest<System.Data.DataTable>() .AS("Order")//表名 //第一个参数datatable //第二个参数主键 //第三个参数是不是自增 true为自增 .BulkMerge(dt, new string[] { "Id" },true);
普通查询就行了性能超快
db.Queryable<Order>().ToList();//比Dapper略快 //分页降低内存 适合复杂的DTO转换和导出 List<Order> order = new List<Order>(); db.Queryable<Order>().ForEach(it=> { order.Add(it); /*禁止这儿操作数据库因为会循环*/} ,2000);
直接用分页删除就行了
db.Deleteable<Order>(list).PageSize(1000).ExecuteCommand();
winform中推荐用异步事件 async await
如果用同步方法要加Task.Run 不然会卡死UI
//方式1:使用异步方法 private async void MyButton_Click(object sender, EventArgs e) { // async await不能少 var result =await db.Fastest<Order>().BulkCopyAsync(lstData) // 使用result... } //使用同步方法要加Task.Run Task.Run(()=>{ var db=Db.CopyNew(); db.Fastest<DC_Scene>().BulkCopy(lstData); });
插入的列越多,越能体现性能
Db.Fastest.BulkCopy 比 EFCore.Bulkextension 快30% 插入的列的数量越多越强
Db.Fastest.BulkUpdate 是 EFCore.Bulkextension 2-3倍
SqlSugar>EFCore.Bulkextension>Dapper (ef plus & dapper plus 收费框架 未进行测试)
注意:不支持默认值和计算列
数据库 | API | 支持自增 | 使用说明 |
SqlSever | 全支持 | 是 | |
MySql | 全支持 | 是 | 连接字符串要加AllowLoadLocalInfile=true |
PgSql | 全支持 | 否 | 不支持自增或者特殊默认值 |
Oracle | 全支持 5.0.4.7 只支持 .NET CORE | 否 | 缺点:不支持事务,无视唯一索引可以插入重复数据,尽量用GUID或者雪花ID,调试不要来回拖断点防止插入重复数据 破坏索引 出错后方案: 删除主键 1.alter table TESTFAST11 drop primary key 2.找出重复数据删掉 3.在重新创建索引 推荐:下面写法性能可以满足尽量用下面写法 db.Insertable(List<实体>).UseParameter().ExecuteCommand() |
Sqlite | 全支持 5.0.5.3 | 是 | |
达梦 | 全支持 | ||
金仓 | 全支持 |
注意:返回前端雪花ID要转成String,不然前端精度不够(文档插入有细讲)
SnowFlakeSingle.Instance.NextId(); //目前需要实体手动赋值 //多台服务器同时插入一个库需要配置服务器唯一ID //SnowFlakeSingle.WorkId=不同机器配置的唯一数字
并发高用异步方法吐能量能提高
一次插入的数据量越大他的价值越高,比如1000以下就不合算了,数据量小的时候并发吞吐量不如普通插入
await db.Fastest<RealmAuctionDatum>().BulkCopyAsync(GetList()) //用异步await不能少 await db.Fastest<RealmAuctionDatum>().BulkUpdateAsync(GetList()) //winform写法需要注意 ,文档最上面
db.Fastest<OrderSpliteTest>().SplitTable().BulkCopy(List<OrderSpliteTest>); db.Fastest<OrderSpliteTest>().SplitTable().BulkUpdate(List<OrderSpliteTest>); //实体定义看分表文档 //winform写法需要注意与上面 文档最上面
分页可以降低内存占用
//如果数据库现有数据比较多出现比较慢,这个时候可以试试分页 db.Fastest<Order>().PageSize(300000).BulkCopy(insertObjs);
考虑到性能默认不会开启DataExecuting,需要下面写法
db.Fastest<OrderSpliteTest>().EnableDataAop().BulkCopy(List<OrderSpliteTest>)
老版本可以这么用,性能不如db.Fastest
//(3)、blukCopy插入 //只适合1万以上超大数据插入或者上面数据插入慢情况,小数据插入性能不行,不是所有库都支持 db.Insertable(List<实体>).UseSqlServer().ExecuteBulkCopy() db.Insertable(List<实体>).UseMySql().ExecuteBulkCopy()//高版本Mysql.data驱动,连接字符串要加AllowLoadLocalInfile=true db.Insertable(List<实体>).UseOracle().ExecuteBulkCopy()//5.0.3.8-Preview //SqlBulkCopy
2016 © donet5.comApache Licence 2.0