WCF服务中DataServiceContext插入慢,求批量插入优化方案
Entity Framework 批量插入优化:按100/200条批次保存
原代码问题分析
你当前的代码不仅存在性能瓶颈,还有两处逻辑错误:
- 赋值错误:
data.id=a.id; data.name=a.name;错误引用了列表a的属性,而非循环项d的属性,会导致所有插入数据都是同一个值。 - 单次批量过大:一次性向
DataServiceContext添加1000条对象后再执行SaveChanges,上下文需要维护大量对象状态,生成的请求复杂度极高,直接导致6分钟的耗时。
优化方案:按批次拆分保存
核心思路是将1000条数据拆分为每100或200条的小批次,每个批次单独创建上下文、批量添加实体后执行保存,避免单次处理过多数据引发的性能问题。
优化后代码示例
// 设定批次大小,可根据实际测试调整为100或200 int batchSize = 100; // 将原始列表拆分为多个批次 var batches = a.Select((person, index) => new { Person = person, Index = index }) .GroupBy(item => item.Index / batchSize) .Select(group => group.Select(g => g.Person).ToList()); foreach (var batch in batches) { // 使用using块自动管理上下文生命周期,避免资源泄漏 using (var context = new servicereferences.MiddleTier()) // 这里是你的DataServiceContext实例 { // 关闭自动变更检测,减少插入时的性能开销 context.AutoDetectChangesEnabled = false; foreach (var d in batch) { // 创建对应的数据库实体对象(注意:此处应为实体类,而非上下文类) var dataEntity = new servicereferences.PeopleEntity(); dataEntity.id = d.id; dataEntity.name = d.name; // 向上下文添加实体 context.AddObject("datas", dataEntity); } // 执行当前批次的保存操作 context.SaveChanges(); } }
额外性能优化点
- 调整批次大小:根据数据库性能、网络延迟情况,测试100、200甚至500条的批次效果,找到最优阈值。
- 禁用延迟加载:如果上下文仅用于插入操作,禁用延迟加载可避免不必要的关联查询开销:
context.Configuration.LazyLoadingEnabled = false; - 使用AddRange批量添加:若使用EF6及以上版本,
AddRange可替代循环添加,进一步减少开销:var entities = batch.Select(d => new servicereferences.PeopleEntity { id = d.id, name = d.name }).ToList(); context.AddRange(entities); - 优化数据库索引:检查目标表的索引,避免在插入频繁的字段上创建过多非必要索引,降低插入时的索引维护开销。
内容的提问来源于stack exchange,提问作者Sathish Thulasiraman
相关产品推荐
相关产品推荐

