专栏首页雪雁的专栏EFCore批量操作,你真的清楚吗

EFCore批量操作,你真的清楚吗

背景

EntityFramework Core有许多新的特性,其中一个重要特性便是批量操作。批量操作意味着不需要为每次Insert/Update/Delete操作发送单独的命令,而是在一次SQL请求中发送批量组合指令。

EFCore批量操作实践

批处理是期待已久的功能,社区多次提出要求。现在EFCore支持开箱即用确实很棒,可以提高应用程序的性能和速度。

1

对比实践

以常见的批量插入为例,使用SQL Server Profiler观察产生并执行的SQL语句。

// category表添加3条记录并执行保存
using (var c= new SampleDBContext())
{
    c.Categories.Add(new Category() { CategoryID = 1, CategoryName = "Clothing" });
    c.Categories.Add(new Category() { CategoryID = 2, CategoryName = "Footwear" });
    c.Categories.Add(new Category() { CategoryID = 3, CategoryName = "Accessories" });
    c.SaveChanges();
}

当执行SaveChanges(), 从SQL Profiler追溯到的SQL:

exec sp_executesql N'SET NOCOUNT ON;INSERT INTO [Categories] ([CategoryID], [CategoryName])
VALUES (@p0, @p1),(@p2, @p3),(@p4, @p5);',N'@p0 int,@p1 nvarchar(4000),@p2 int,@p3 nvarchar(4000),@p4 int,@p5 nvarchar(4000)',
@p0=1,@p1=N'Clothing',@p2=2,@p3=N'Footwear',@p4=3,@p5=N'Accessories'

如你所见,批量插入没有产生3个独立的语句,而是被组合为一个传参存储过程脚本(用列值作为参数);如果使用EF6执行相同的代码,则在SQL Server Profiler中将看到3个独立的插入语句 。下面是EFCore、EF6批量插入的对比截图:

① 就性能和速度而言,EFCore批量插入更具优势

② 若数据库是针对云部署,EF6运行这些查询,还将产生额外的流量成本

经过验证:EFCore批量更新、批量删除功能,EFCore均发出了使用sp_executesql存储过程+批量参数构建的SQL脚本。

2

深入分析

起关键作用的存储过程sp_executesql:可以多次执行的语句或批处理 (可带参)

- Syntax for SQL Server, Azure SQL Database, Azure SQL Data Warehouse, Parallel Data Warehouse  
  
sp_executesql [ @stmt = ] statement  
[   
  { , [ @params = ] N'@parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' }   
     { , [ @param1 = ] 'value1' [ ,...n ] }  
]

注意官方限制:

The amount of data that can be passed by using this method is limited by the number of parameters allowed. SQL Server procedures can have, at most, 2100 parameters. Server-side logic is required to assemble these individual values into a table variable or a temporary table for processing. // SQL存储过程最多可使用2100个参数

3

豁然开朗

SqlServer sp_executesql存储过程最多支持2100个批量操作形成的列值参数,所以遇到很大数量的批量操作,EFCore SqlProvider会帮我们将批量操作分块传输,这也是我们在实际大批量使用时看到分块发送的原因。

EFCore开放了【配置关系型数据库批量操作大小】:

protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
{
    string sConnString = @"Server=localhost;Database=EFSampleDB;Trusted_Connection=true;";
    optionbuilder.UseSqlServer(sConnString , b => b.MaxBatchSize(1)); 
   // 批量操作的SQL语句数量,也可设定为1禁用批量插入
}

总结

① EFCore 相比EF6,已经支持批量操作,能有效提高应用程序的性能

② EFCore的批量操作能力,由对应的DataBaseProvider支撑(Provider实现过程跟背后的存储载体密切相关);关注SQL存储过程sp_executesql,官方明文显示批量操作的列值参数最多2100个,这个关键因素决定了在大批量操作的时候 依旧会被分块传输。

③ 另外一个批量操作的方法,这里也点一下:构造Rawsql 【EFCore也支持Rawsql】

  sqlite不支持存储过程,为批量插入提高性能,可采用此方案:

var insertStr = new StringBuilder();
insertStr.AppendLine("insert into ProfileUsageCounters (profileid,datetime,quota,usage,natureusage) values");
var txt = insertStr.AppendLine(string.Join(',', usgaeEntities.ToList().Select(x =>
{
       return $"({x.ProfileId},{x.DateTime},{x.Quota},{x.Usage},{x.NatureUsage})";
}).ToArray()));
await _context.Database.ExecuteSqlCommandAsync(txt.ToString());

+ https://github.com/aspnet/EntityFrameworkCore/issues/6604

+ https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters?redirectedfrom=MSDN

本文分享自微信公众号 - magiccodes(xl----0)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [VSCode插件推荐] Code Runner: 代码一键运行,支持超过40种语言

    安装好Code Runner之后,打开你所要运行的文件,有多种方式来快捷地运行你的代码:

    心莱科技雪雁
  • 代码编辑器横评:为什么 VS Code 能拔得头筹

    2015 年 4 月 29 日的 Build 大会上,微软发布了 Visual Studio Code 第一个预览版本。短短四年时间里,VS Code 高速成长...

    心莱科技雪雁
  • Docker最全教程——数据库容器化(十一)

    终于按时完成第二篇。本来准备着手讲一些实践,但是数据库部分没有讲到,部分实践会存在一些问题,于是就有了此篇以及后续——数据库容器化。本篇将从SQL Server...

    心莱科技雪雁
  • 又一家企业被“勒索”遭殃,企业数据安全路在何方

    2018年7月8日18:02,安恒信息应急响应中心接到某企业电话求救——公司自动化企业资源管理ERP系统被恶意加密,并提示支付比特币才能解密。该ERP系统中的数...

    安恒信息
  • Python的cookie处理分享

    py3study
  • kube-scheduler深度学习批处理任务定制化开发

    深度学习中经常会出现多机多卡的任务,也就是同事会起多个pod,但是这多个pod属于同一个任务。

    sealyun
  • Python中的匿名函数及递归思想简析

    上次咱们基本说了一下函数的定义及简单使用,Python中的基本函数及其常用用法简析,现在咱们整点进阶一些的。同样都是小白,咱也不知道实际需要不,但是对于函数的执...

    Python进阶者
  • 今日头条靠“赞助”拿到人工智能最高奖?价值观缺失是死穴

    12月23日,今日头条凭借与北京大学计算机所联合研发的AI写稿机器人,获得第七届吴文俊人工智能技术发明奖二等奖。不过值得玩味的是,头条的LOGO也赫然出现在大会...

    企鹅号小编
  • CocoaPods之Podfile\Podfile.lock什么是Podfile ?指定pod版本Podfile和Target什么是Podfile.lock?

    VV木公子
  • Magic Leap在增强现实中展示了外形如同真人的AI

    Magic Leap展示了Mica的演示,这是一种外形如同真人的AI,可以在公司的增强现实眼镜Magic Leap One Creator Edition中观看...

    AiTechYun

扫码关注云+社区

领取腾讯云代金券