You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core使用IncludeGraph做BulkInsert到SQL Server速度慢如何优化?

EF Core Bulk Extensions 大批量对象图插入性能优化方案

调整BulkInsert运行参数

  • 调整BatchSize到2000~5000区间测试最优值,同步设置BulkCopyTimeout = 0(不限制超时),当前1000的批次偏小,会增加批量提交的总次数
  • 显式配置批量操作开关,关闭不需要的逻辑:
    BulkInsert(entities, o => 
    {
        o.IncludeGraph = true;
        o.UseTempDB = true;
        o.AutoMapOutputIdentity = true;
        o.InsertIfNotExists = false;
    });
    
    UseTempDB可以降低对象图关联匹配时的磁盘IO开销,你后续统一做去重,不需要插入时判断重复,关闭InsertIfNotExists可减少30%左右的计算开销
  • 如果对象图层级不超过3级,额外开启o.IncludeGraphSingleSession = true,减少上下文切换开销

SQL Server端优化

  • 插入前临时删除所有非聚集索引,插入完成后统一重建:插入过程中维护非聚集索引的开销会占到总写入开销的60%以上,你当前每个导航属性都对应非聚集索引,这是核心性能瓶颈之一
  • 插入阶段临时关闭外键约束检查,插入完成后再恢复:
    -- 关闭指定表所有外键约束
    ALTER TABLE [表名] NOCHECK CONSTRAINT ALL
    -- 插入完成后恢复
    ALTER TABLE [表名] CHECK CONSTRAINT ALL
    
    你后续会做数据清理,插入阶段的外键检查属于完全冗余开销
  • 调整数据库文件自动增长策略:将数据文件、日志文件的自动增长步长设置为1GB,避免默认10%增长策略带来的频繁文件扩容锁
  • 确认数据库文件存放在SSD介质上,机械盘的顺序写入性能比SSD低5~10倍,会直接拖慢批量插入速度

程序端优化

  • 每个插入批次单独创建DbContext,用完立即释放,避免上下文跟踪的实体数量持续增长,导致内存占用过高、实体匹配效率下降
  • 批次内提前做子实体去重:对同一批次内的子实体按唯一键做Hash去重,避免重复写入临时表,减少数据传输和计算开销
  • 开启服务器GC模式,在项目.csproj文件中添加配置:
    <PropertyGroup>
      <ServerGarbageCollection>true</ServerGarbageCollection>
    </PropertyGroup>
    
    大内存场景下可大幅降低GC停顿时间,提升多线程处理效率

极端性能场景优化方案

如果以上调整后仍达不到预期,可放弃IncludeGraph自动处理逻辑,改为手动拆分实体插入:

  1. 先批量插入所有根实体,获取生成的自增主键
  2. 关联根主键后批量插入一级子实体,获取子实体主键
  3. 以此类推处理所有层级的实体
    该方式比IncludeGraph自动处理速度快2~3倍,但需要自行实现主键映射逻辑

内容的提问来源于stack exchange,提问作者Martin Kirk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 06:45:03