大数据写入、更新,大数据更新 ORM, db.Fastest文档

1、功能介绍  (需要版本5.0.45)

海量数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现

列越多转换越慢,SqlSugar将转换性能做到极致,并且采用数据库最佳API

操作数据库达到极限性能  


正常使用如下:

db.Fastest<DC_Scene>().BulkCopy(lstData);
db.Fastest<RealmAuctionDatum>().BulkUpdate(GetList())
//db.Queryable<Order>().ToList();大数据查询也很快 比Dapper略快
//更多用法看 标题3  :支持 更新、分页等

//超过50万 占内存大 这个时候可以试试分页
db.Fastest<Order>().PageSize(300000).BulkCopy(insertObjs);

WinFom用法:

//WinFrom中 不能直接用,会出现卡住不动,因为WinFrom不支持直接调用异步 ,需要加委托 
//bulkCopy 和 bulkCopyAsync 底层都是异步实现
Func<int> func = () =>db.Fastest<DC_Scene>().BulkCopy(lstData);
func.BeginInvoke(x=>
{
   var result = func.EndInvoke(x);//获取返回值
   MessageBox.Show($"成功添加数据:{result}条");
}, null);

2、详细教程

注意:winform写法有点区别看一下不同点

//插入 100万 10秒不到 
db.Fastest<RealmAuctionDatum>().BulkCopy(GetList());//性能比 EFCore.Bulkextension 快30% (列越多差距越大)

//使用datatable 5.0.7.7
db.Fastest<System.Data.DataTable>().AS("order").BulkCopy(dataTable);

//更新
db.Fastest<RealmAuctionDatum>().BulkUpdate(GetList());//是 EFCore.Bulkextension 2-3倍,30列100万8秒更新完
db.Fastest<RealmAuctionDatum>().BulkUpdate(GetList(),new string[]{"id"},new string[]{"name","time"})//无主键用法
//注意:更新情况比较复杂,有些表会出现比较慢的情况
//主键尽量用(没主键性能会慢) long或者int ,然后 list在内存中按主键排序在传给ORM 
//然后设置.PageSize(1000).BulkUpdate(GetList())  进行内部分页更新


//表设置别名
db.Fastest<RealmAuctionDatum>().AS("tableName").BulkCopy(GetList())

//分页
db.Fastest<Order>().PageSize(300000).BulkCopy(insertObjs);

//MySql utf8mb4
db.Fastest<Order>().SetCharacterSet("utf8mb4").BulkCopy(insertObjs)


3、产品对比

插入的越多,越能体现性能

Db.Fastest.BulkCopy  比 EFCore.Bulkextension 快30%  插入的列的数量越多越强

Db.Fastest.BulkUpdate  是 EFCore.Bulkextension 2-3倍

SqlSugar>EFCore.Bulkextension>Dapper (ef plus & dapper plus 收费框架 未进行测试)



4、数据库支持

注意:不支持默认值和计算列

数据库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


5、更新或插入

对于海量数据并且性能要高的可以用下面的方式实现更新保存功能

  var x= db.Storageable<Order>(data).ToStorage();//最好是主键为条件 varchar小于50
     x.BulkCopy();//不存在插入
     x.BulkUpdate();//存在更新
     
     //winform写法需要注意 ,文档最上面


6、雪花ID

注意:返回前端雪花ID要转成String,不然前端精度不够(文档插入有细讲)

 SnowFlakeSingle.Instance.NextId(); //目前需要实体手动赋值
 //多台服务器同时插入一个库需要配置服务器唯一ID
 //SnowFlakeSingle.WorkId=不同机器配置的唯一数字


7、并发高情况

并发高用异步方法吐能量能提高 

一次插入的数据量越大他的价值越高,比如1000以下就不合算了,数据量小的时候并发吞吐量不如普通插入

await db.Fastest<RealmAuctionDatum>().BulkCopyAsync(GetList()) //用异步await不能少
await db.Fastest<RealmAuctionDatum>().BulkUpdateAsync(GetList())
//winform写法需要注意 ,文档最上面


8、分表支持5.0.4.8

 db.Fastest<OrderSpliteTest>().SplitTable().BulkCopy(List<OrderSpliteTest>);
 db.Fastest<OrderSpliteTest>().SplitTable().BulkUpdate(List<OrderSpliteTest>);
 //实体定义看分表文档
 //winform写法需要注意与上面 文档最上面


9、内存性能优化

分页可以降低内存占用

//如果数据库现有数据比较多出现比较慢,这个时候可以试试分页
db.Fastest<Order>().PageSize(300000).BulkCopy(insertObjs);


10、老版本

老版本可以这么用,性能不如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


文档:SqlSugar5.0