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

ABP框架中InsertMany批量插入7万+数据速度极慢求助

ABP + EF Core 批量插入性能优化方案

针对你遇到的7万条数据批量插入慢、批次递增耗时变长的问题,以下是具体解决办法:

1. 关闭变更跟踪与自动检测

EF Core默认会跟踪所有添加的实体,批量插入时这会产生巨大的性能开销。在批量操作中临时关闭相关功能:

using (var uow = _unitOfWorkManager.Begin())
{
    var dbContext = _dbContextProvider.GetDbContext();
    // 关闭自动变更检测与实体验证
    dbContext.ChangeTracker.AutoDetectChangesEnabled = false;
    dbContext.ValidateOnSaveEnabled = false;

    dbContext.Set<YourEntity>().AddRange(batchEntities);
    await dbContext.SaveChangesAsync();

    // 恢复默认设置
    dbContext.ChangeTracker.AutoDetectChangesEnabled = true;
    dbContext.ValidateOnSaveEnabled = true;

    await uow.CompleteAsync();
}

2. 清理变更跟踪避免批次变慢

每批次插入后,EF仍会保留实体的跟踪信息,导致后续批次内存占用和处理时间递增。每次批次完成后清理跟踪:

await dbContext.SaveChangesAsync();
dbContext.ChangeTracker.Clear(); // 清理已跟踪的实体

3. 临时关闭ABP审计日志

ABP默认开启的审计日志会记录每一条插入操作,批量场景下会生成大量日志拖慢速度。在UnitOfWork中临时禁用:

using (var uow = _unitOfWorkManager.Begin(new UnitOfWorkOptions 
{ 
    IsTransactional = true, 
    DisableAuditing = true // 关闭审计
}))
{
    // 批量插入逻辑
    await uow.CompleteAsync();
}

4. 使用原生SQL批量插入(TVP方式)

通过SQL Server的表值参数(Table-Valued Parameter)实现高效批量插入,避开EF的ORM开销:

  1. 先在SQL Server中创建用户定义表类型:
CREATE TYPE dbo.YourEntityType AS TABLE (
    Property1 NVARCHAR(100),
    Property2 INT,
    -- 其他对应字段
)
  1. 代码中构造DataTable并执行原生SQL:
var dataTable = new DataTable();
dataTable.Columns.Add("Property1", typeof(string));
dataTable.Columns.Add("Property2", typeof(int));

// 填充数据到DataTable
foreach (var entity in batchEntities)
{
    dataTable.Rows.Add(entity.Property1, entity.Property2);
}

await _dbContext.Database.ExecuteSqlRawAsync(
    @"INSERT INTO YourEntities (Property1, Property2)
      SELECT Property1, Property2 FROM @tvp",
    new SqlParameter("@tvp", SqlDbType.Structured)
    {
        TypeName = "dbo.YourEntityType",
        Value = dataTable
    }
);

5. 使用EFCore.BulkExtensions扩展

EF Core本身没有内置BulkInsert,你可以通过第三方库实现,ABP不会限制这个功能:

  1. 安装NuGet包:Install-Package EFCore.BulkExtensions
  2. 在UnitOfWork中直接调用:
using (var uow = _unitOfWorkManager.Begin())
{
    var dbContext = _dbContextProvider.GetDbContext();
    await dbContext.BulkInsertAsync(batchEntities);
    await uow.CompleteAsync();
}

6. 其他优化建议

  • 调整批次大小:测试1000-5000条的批次规模,找到适合你环境的最优值;
  • 临时禁用非聚集索引:插入前禁用表上的非聚集索引,完成后重建,减少插入时的索引维护开销;
  • 简化实体关联:批量插入时尽量避免加载或关联复杂导航属性,减少EF的额外处理逻辑。

内容的提问来源于stack exchange,提问作者Adrian Inman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:33:15