大数据写入、大数据批量操作、更新,大数据更新 ORM 文档
1、功能介绍 (
需要版本5.0.45
)
海量数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现
当
列越多转换越慢
,SqlSugar将转换性能做到极致,并且采用数据库最佳API
操作数据库达到极限性能
正常使用如下:
db.Fastest<DC_Scene>().BulkCopy(lstData);//插入
db.Fastest<RealmAuctionDatum>().BulkUpdate(GetList())//更新
//db.Queryable<Order>().ToList();大数据查询也很快 比Dapper略快
//更多用法看 标题2 :支持 更新、分页等
//超过50万 占内存大 这个时候可以试试分页
db.Fastest<Order>().PageSize(300000).BulkCopy(insertObjs);
db.Fastest<RealmAuctionDatum>().PageSize(300000).BulkUpdate(GetList())//更新
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<Test001_model>().BulkUpdate(GetList(),new string[] { "name"});//只更新固定列,需要有主键
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、更新或插入
对于海量数据并且性能要高的可以用下面的方式实现更新保存功能
//一起写 : 5.1.4.62
db.Storageable<Order>(data).ExecuteSqlBulkCopy()
//分开写
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