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

.NET Core删除数据库5000+条记录耗时过慢优化方案咨询

性能问题根因

你现有代码的性能瓶颈来自循环内的单次查询+单次提交:5000条记录会产生至少10000次数据库往返请求(每次循环1次查询+1次提交),大量IO等待导致耗时极长。

优化方案

方案1:原生EF Core优化(无第三方依赖)

先批量查询所有符合条件的记录,再批量删除、单次提交,仅需2次数据库往返,适配.NET Core 2.1版本,无需引入额外包:

public async Task<bool> deleteAdhocDetails(int[] id)
{
    // 单次查询所有符合条件的记录
    var toDeleteList = await _context.AdhocRewardInfo
        .Where(d => id.Contains(d.RowID) && d.HaloRewardCode != null)
        .ToListAsync();
    
    if (!toDeleteList.Any()) return false;

    try
    {
        // 批量标记删除
        _context.AdhocRewardInfo.RemoveRange(toDeleteList);
        // 单次提交所有删除操作
        await _context.SaveChangesAsync();
        return true;
    }
    catch (Exception e)
    {
        // 注意:不要写throw e,会丢失原始异常堆栈,直接throw即可
        throw;
    }
}

该方案性能相比原代码可提升数十倍。

方案2:原生SQL批量删除(性能最高)

无需先查询数据,直接在数据库层执行删除操作,仅需1次数据库请求:

public async Task<bool> deleteAdhocDetails(int[] id)
{
    // 参数化处理避免SQL注入
    var parameters = new List<SqlParameter>();
    var paramNames = new List<string>();
    for (int i = 0; i < id.Length; i++)
    {
        var paramName = $"@Id{i}";
        paramNames.Add(paramName);
        parameters.Add(new SqlParameter(paramName, id[i]));
    }

    var sql = $"DELETE FROM AdhocRewardInfo WHERE HaloRewardCode IS NOT NULL AND RowID IN ({string.Join(",", paramNames)})";
    try
    {
        var affectedRows = await _context.Database.ExecuteSqlCommandAsync(sql, parameters);
        return affectedRows > 0;
    }
    catch (Exception e)
    {
        throw;
    }
}

注意:需保证RowID字段有索引(主键默认带索引),否则大表查询依然会慢。

方案3:EFCore.BulkExtensions正确用法

你之前用BulkDelete没有效果大概率是用法错误,正确的批量删除无需循环操作:

public async Task<bool> deleteAdhocDetails(int[] id)
{
    var toDeleteList = await _context.AdhocRewardInfo
        .Where(d => id.Contains(d.RowID) && d.HaloRewardCode != null)
        .ToListAsync();
    
    if (!toDeleteList.Any()) return false;

    try
    {
        // 直接调用批量删除方法,内部自动生成批量SQL
        await _context.BulkDeleteAsync(toDeleteList);
        return true;
    }
    catch (Exception e)
    {
        throw;
    }
}
额外优化建议
  • 如果删除数据量超过10万条,可以分批执行(每次删1000-2000条),避免长时间锁表影响其他业务。
  • 前端调用无需修改,现有TS代码逻辑可以正常适配优化后的后端接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:09:04