我有这样的代码,我在StackOverflow发现:更新数据库运行速度非常慢
public static class EntityFrameworkUtil
{
public static IEnumerable<T> QueryInChunksOf<T>(this IQueryable<T> queryable, int chunkSize)
{
return queryable.QueryChunksOfSize(chunkSize).SelectMany(chunk => chunk);
}
public static IEnumerable<T[]> QueryChunksOfSize<T>(this IQueryable<T> queryable, int chunkSize)
{
int chunkNumber = 0;
while (true)
{
var query = (chunkNumber == 0)
? queryable
: queryable.Skip(chunkNumber * chunkSize);
var chunk = query.Take(chunkSize).ToArray();
if (chunk.Length == 0)
yield break;
yield return chunk;
chunkNumber++;
}
}
}
我用这个像这样:
int counter = 0;
foreach (var chunk in _sdb.Posts.OrderBy(c => c.Id).QueryChunksOfSize(100))
{
foreach(var post in chunk)
{
post.Floor= CorrectFloor(post);
post.RealAge= AgeCalculator(post);
post.Area= TerasCheck(post);
_sdb.Entry(post).State = System.Data.Entity.EntityState.Modified;
counter++;
}
_sdb.SaveChanges();
Console.WriteLine("SaveChanges worked, counter : " + counter);
}
此代码应该更新300000行。代码起初运行速度很快,但现在它运行速度非常缓慢,并且在第30000行。你能告诉我为什么这个代码运行速度很慢,我怎样才能让它更快?谢谢。
我想这就是db规范化问题。但通常情况下,您可以通过调用循环外的保存更改来提高性能。 – Emad
@Emad为整个数据库调用SaveChanges是个好主意吗? – jason
我认为'SaveChanges()'目前处于正确的位置,因为它在每100个项目后都会保存(尽管我会将它提升到1000)。我怀疑减速与更改跟踪有关。我不是EF的专家,但我认为使用'AsNoTracking()'会有所帮助。在第一个foreach中_sdb.Posts.AsNoTracking()。OrderBy(c => c.Id).QueryChunksOfSize(100))'中的var chunk。 –