我加载了 8,956 行数据,只为了翻转一个布尔值
来源:dev.to — 2026-08-03
📋 概述
作者用 EF Core 写的一个归档夜间任务:把超过 90 天的已交付订单标记为已归档。他打开 SQL 日志才发现这段四行代码把 8,956 行完整记录全查出来,再逐行发 UPDATE 写回 8,956 个布尔值——75 MB 分配、355 毫秒、8,957 条 SQL 命令。改用 EF 7 就有的 ExecuteUpdate 后,同一条件只发一条 SQL,10.6 毫秒、68 KB 分配,性能提升 33 倍、分配减少约 1100 倍。
🔑 核心要点
- load-modify-save 的代价:先 ToList() 再逐行改,实际是 1 条 SELECT + 8,956 条 UPDATE,75 MB 分配
- 75MB 来源:EF 变更跟踪会为每个被追踪实体拍快照,等于在内存里放两份表数据只为改一列
- ExecuteUpdate 一招制胜:EF 7 起的集合更新 API 直接发一条 UPDATE WHERE,1 条命令、10.6ms、68KB
- 绕过追踪器的陷阱:ExecuteUpdate 不更新已被追踪的实体,同一 context 混用会产生“自信的错误答案”
- 何时仍用实体:触发逐实体领域事件、审计拦截器或业务规则否决时,load-modify-save 才有价值
💡 金句
load-modify-save is for entities with behavior, and it earns its cost a handful of rows at a time.
👍 0
👎 0
← 返回 Dev.to 首页