2012-07-26 40 views
0

今天早上我写了一个快速客户端,当我注意到后续保存后,性能会降低,只是将一堆数据插入到表存储中。为什么性能会随着对TableServiceContext.SaveChanges的多次调用而降低

public class MyObject : TableServiceEntity 
{ 
    public MyObject() 
    { 
     this.RowKey = Guid.NewGuid().ToString(); 
    } 

    public string SomeProperty { get; set; } 
} 

然后,我有一个简单的代码块添加一些数据....

Stopwatch timer = new Stopwatch(); 
      for (int i = 0; i < target/50; i++) 
      { 
       CloudTableClient client = account.CreateCloudTableClient(); 
       client.CreateTableIfNotExist(entitySet); 
       TableServiceContext context = client.GetDataServiceContext(); 

       timer.Reset(); 
       timer.Start(); 
       for (int x = 0; x < i * 50; x++) 
       { 
        var obj = new MyObject(); 

        context.AddObject(entitySet, obj); 
        context.SaveChanges(); 
       } 
       total += 100; 
       timer.Stop(); 

       Console.WriteLine("Added 100 entities in {0} seconds; total: {1}", timer.Elapsed.Seconds, total); 
      } 

这里是我所看到的,当它运行(控制台应用程序)

Added 100 entities in 0 seconds; total: 100 

Added 100 entities in 0 seconds; total: 200 

Added 100 entities in 1 seconds; total: 300 

Added 100 entities in 2 seconds; total: 400 

Added 100 entities in 4 seconds; total: 500 

Added 100 entities in 4 seconds; total: 600 

Added 100 entities in 6 seconds; total: 700 

Added 100 entities in 6 seconds; total: 800 

为什么性能下降?

  • 如果我移动背景下,客户端和/或账户圈外
  • 实施context.ResolveType并没有解决问题
  • 分析之后,在没有发生变化, context.SaveChanges方法是瓶颈的地方
  • 重新运行该应用程序会重现相同的结果;即使数据库中有数百/数千个其他实体。

回答

1

我相信你的测试代码有一个错误,在这一行。

for (int x = 0; x < i * 50; x++) 

你迭代高达i * 50倍,因此通过外循环,每次你会比前次增加50多个实体。第一次通过添加0个实体,确实非常快。然后是50,然后是100,然后是150,等等,这是被掩盖的,因为你的日志代码每次都会盲目地向计数增加100,即使这不是你实际添加的数字。你可能想要的是:

for (int x = 0; x < 100; x++) 

关于分析结果,这段代码的大部分工作在内存中的数据。 SaveChanges()会进行网络通话,这就是为什么它占据了花费的时间。

我意识到这是测试代码。但是,如果您实际上试图将大量实体添加到单个PartitionKey,建议使用批处理。

+0

谢谢!它惊人的容易忽略它! – 2012-07-26 18:38:08

相关问题