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

.NET Core 3.1优化:TravelPort API数据库存储耗时过长求助

优化EF Core SaveChangesAsync写入日志的性能方案
  • 减少数据库写入的数据量
    你代码里已经生成了reqFileName和resFileName,说明请求/响应内容已经存储到文件系统。没必要在数据库里重复存储完整JSON字符串,只需把文件路径存入数据库即可。这样写入数据量会大幅减少,直接解决大字段写入缓慢的问题。

  • 使用独立DbContext实例处理日志写入
    不要复用业务逻辑的DbContext写日志,单独创建新的DbContext实例专门处理日志操作。业务上下文可能追踪了大量实体,SaveChanges时会遍历所有追踪对象,导致耗时增加。独立上下文只处理当前日志实体,能大幅提升写入速度:

    // 单独创建日志专用上下文实例
    using var logContext = new YourLogDbContext();
    await logContext.Logs.AddAsync(new Log()
    {
        RequestPath = reqFileName, // 存储文件路径而非完整JSON
        ResponsePath = resFileName,
        RequestType = "Air_Seat_Map",
        Success = true,
    });
    await logContext.SaveChangesAsync();
    
  • 优化JSON序列化开销
    如果必须存储JSON字符串,可通过以下方式优化序列化过程:

    • 复用JsonSerializerOptions实例,避免每次序列化都创建新实例,减少内存分配
    • 对大对象使用异步序列化,减少主线程阻塞:
      // 提前定义复用的序列化配置
      private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions()
      {
          WriteIndented = false, // 关闭格式化进一步缩小体积
          IgnoreNullValues = true
      };
      
      // 异步序列化
      var reqJson = await JsonSerializer.SerializeAsync(seatMapReq, _serializerOptions);
      var resJson = await JsonSerializer.SerializeAsync(res.SeatMapRsp, _serializerOptions);
      
    • 考虑换用更高效的序列化库(如MessagePack),序列化速度比System.Text.Json更快,生成的内容体积更小。
  • 绕过EF Core追踪,直接执行原生SQL
    日志写入是简单插入操作,不需要EF的实体追踪和验证逻辑,直接用原生SQL插入能跳过EF的额外开销:

    var sql = @"INSERT INTO Logs (Request, Response, ReqFileName, ResFileName, RequestType, Success)
                VALUES (@Request, @Response, @ReqFileName, @ResFileName, @RequestType, @Success)";
    await context.Database.ExecuteSqlRawAsync(sql,
        new SqlParameter("@Request", JsonSerializer.Serialize(seatMapReq)),
        new SqlParameter("@Response", JsonSerializer.Serialize(res.SeatMapRsp)),
        new SqlParameter("@ReqFileName", reqFileName),
        new SqlParameter("@ResFileName", resFileName),
        new SqlParameter("@RequestType", "Air_Seat_Map"),
        new SqlParameter("@Success", true));
    
  • 检查数据库表结构与索引

    • 确保Logs表没有不必要的索引,过多索引会增加写入耗时
    • 对于Request和Response这类大文本字段,使用合适的字段类型(如SQL Server的NVARCHAR(MAX)、MySQL的LONGTEXT),避免因字段类型不匹配导致的隐式转换或存储开销
  • 优化DbContext配置

    • 对日志专用DbContext禁用实体追踪(ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking),减少内存开销和追踪逻辑
    • 检查数据库连接池配置,确保连接字符串中Max Pool Size设置合理,避免因连接等待导致的耗时

内容的提问来源于stack exchange,提问作者hanushi-thana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:15:13