SuperAPI AI 工具集

optimizing-ef-core-queries

编程与开发

查看项目

更新于 10-16 00:05

技能介绍

用途:诊断并修复 Entity Framework Core 慢查询。核心思路是先看生成的 SQL 与查询次数,再做最小改动,改一次测一次,优先减少往返、重复行、扫描和每次调用的翻译开销,而非微优化。

主要能力与用法:

  1. 先捕获 SQL:用 optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information) 或 appsettings.json 中 "Microsoft.EntityFrameworkCore.Database.Command": "Information",并用 .TagWith("...") 标记查询,统计语句数与返回行数。
  2. 保持谓词可索引(sargable):不要把索引列包在函数里,如 CreatedAt.Year == y、ToLower(Name) == n、Price * 1.1 > x、前导通配符 LIKE '%foo',应改写为裸列的范围比较,例如 var start = new DateTime(year, 1, 1); db.Logs.Where(l => l.CreatedAt >= start && l.CreatedAt < start.AddYears(1));。
  3. 热点查询编译:用 EF.CompileQuery / EF.CompileAsyncQuery 生成静态委托复用,仅适合高频同一查询形状。
  4. 消除 N+1:用 Select 投影或 Include 预加载,避免懒加载(不要启用 Proxies 或 virtual 导航)。
  5. 多个集合 Include 用 AsSplitQuery() 拆分,避免笛卡尔积。
  6. 分页优先键集(seek)而非 Skip/Take,如 db.Orders.Where(o => o.Id > lastSeenId).OrderBy(o => o.Id).Take(pageSize);。
  7. 补索引:在模型中配置,如 modelBuilder.Entity<Order>().HasIndex(o => new { o.CustomerId, o.CreatedAt });,再用 dotnet ef migrations add ... 生成迁移;未经用户明确同意不要执行 dotnet ef database update。
  8. 批量更新删除用 ExecuteUpdateAsync/ExecuteDeleteAsync(EF Core 7+),注意绕过变更跟踪与级联。

适用场景:EF Core 查询慢、SQL 语句过多、N+1、集合 Include 膨胀、深分页变慢、索引列被函数包裹导致扫描、高频查询重复翻译。

限制:不适用于 Dapper 或原生 ADO.NET;不要为凑长度编造功能;索引会拖慢写入,避免过度索引;迁移写库需用户批准。