2013-07-03 2 views
0

Ниже приведена программа сокетов, которая получает данные в довольно быстром темпе. Он отлично работает при отключенном разделе CodeFirst. Если я включу его, программа начнет работать нормально, но затем медленно деградирует до точки, где ничего не записывается в SQL EXPRESS 2012 db. Я проверяю это, запустив инструкцию SQL, которая просто выбирает последние пять строк. SQL Management Studio 2012.Codefirst ухудшается со временем

Есть ли что-то, что я делаю неправильно?

select * from [MarketDataEntities] 
where MarketDataEntities.MarketDataEntityID not in (
    select top (
     (select count(*) from [MarketDataEntities]) - 5 
    ) MarketDataEntities.MarketDataEntityID 
    from [MarketDataEntities] 
) 



       using (var dbTDC = new TickDataTestContext()) 
       { 
        var tde = new SymbolTickDataEntity { Symbol = symbol }; 
        if (!dbTDC.SymbolTickDataDbSet.Any(a => a.Symbol.Equals(symbol))) 
        { 
         dbTDC.SymbolTickDataDbSet.Add(tde); 
         dbTDC.SaveChanges(); 
        } 

        var mdde = new MarketDataDepthEntity(); 
        dbTDC.MarketDataDepthDbSet.Add(mdde); 

        dbTDC.SaveChanges(); 

        while (true) 
        { 
         // Wait for next request from client 
         int len = socket.Receive(zmq_buffer); 
         if (len < 1) 
         { 
          Console.WriteLine("Len < 1"); 

          continue; 
         } 

         //Console.WriteLine("Got quote"); 

         count++; 

         // Copy the bytes 
         byte[] bytes = new byte[len]; 
         Buffer.BlockCopy(zmq_buffer, 0, bytes, 0, len); 

         MarketDataDepth mdd = MarketDataDepth.CreateBuilder().MergeFrom(bytes).Build(); 

         PrintMarketDataDepth(mdd); 
#if false 
         for (int i = 0; i < mdd.MdCount; i++) 
         { 
          MarketData md = mdd.MdList[i]; 

          string timestamp = md.Time; 
          int index = timestamp.IndexOf(","); 
          if(-1 != index) 
           timestamp = timestamp.Remove(index); 

          DateTime parseResult; 
          if (false == System.DateTime.TryParseExact(timestamp, format, provider, DateTimeStyles.None, out parseResult)) 
           continue; 

          var mde = new MarketDataEntity 
          { 
           NMDDTag = (long)mdd.NMDDTag, 
           QType = (0 == md.QuoteType ? QuoteType.Bid : QuoteType.Ask), 
           QPrice = md.Price, 
           QSize = md.Size, 
           QSource = md.Source, 
           QLiquidityTag = md.ID, 
           QSilo = md.Silo, 
           QTimeStamp = parseResult 
          }; 

          dbTDC.MarketDataDbSet.Add(mde); 

          mdde.Depth.Add(mde); 
         } 

         if (0 == count % 500) 
          dbTDC.SaveChanges(); 
#endif 
        } 
       } 
      } 
      catch (DbEntityValidationException e) 
      { 
       foreach (var eve in e.EntityValidationErrors) 
       { 
        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", 
         eve.Entry.Entity.GetType().Name, eve.Entry.State); 
        foreach (var ve in eve.ValidationErrors) 
        { 
         Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"", 
         ve.PropertyName, ve.ErrorMessage); 
        } 
       } 

       throw; 
      } 
     } 
    } 

    public enum QuoteType { Bid = 0, Ask } 

    public class MarketDataEntity 
    { 
     [Key] 
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
     public int MarketDataEntityID { get; set; } 

     public long NMDDTag { get; set; } 
     public QuoteType QType { get; set; } 
     public double QPrice { get; set; } 
     public double QSize { get; set; } 
     public string QSource { get; set; } 
     public string QLiquidityTag { get; set; } 
     public string QSilo { get; set;} 
     [Column("timestamp", TypeName = "datetime2")] 
     public DateTime QTimeStamp { get; set; } 
    } 

    public class MarketDataDepthEntity 
    { 
     public int MarketDataDepthEntityID { get; set; } 
     public virtual IList<MarketDataEntity> Depth { get; set; } 

     [Column("timestamp", TypeName = "datetime2")] 
     public DateTime TimeStamp { get; set; } 
     public MarketDataDepthEntity() { Depth = new List<MarketDataEntity>(); } 
    } 

    public class SymbolTickDataEntity 
    { 
     public int SymbolTickDataEntityID { get; set; } 

     [Key] 
     [Required] 
     public string Symbol { get; set; } 

     public virtual IList<MarketDataDepthEntity> Mdds { get; set; } 
     public SymbolTickDataEntity() { Mdds = new List<MarketDataDepthEntity>(); } 
    } 

    public class TickDataTestContext : DbContext 
    { 
     public DbSet<MarketDataEntity> MarketDataDbSet { get; set; } 
     public DbSet<MarketDataDepthEntity> MarketDataDepthDbSet { get; set; } 
     public DbSet<SymbolTickDataEntity> SymbolTickDataDbSet { get; set; } 
    } 
+0

Сколько данных вы добавляете в БД? Сколько строк приблизительно и в течение какого периода времени? – Kevin

+0

Хорошо, сейчас это верх книги. Это что-то вроде 2 000 000 строк на символ в день. Так что примерно 50 000 000 строк в день? Но он деградирует в течение примерно десяти минут написания. – user1676605

ответ

2

Из вашего кода видно, что вы сохраняете объект TickDataTestContext на всю жизнь своего приложения. Так как вы продолжаете добавлять данные, локальный кеш продолжает увеличивать использование памяти, что приводит к снижению производительности.

Вы должны переписать код для создания нового экземпляра TickDataTestContext для каждого запроса, который необходимо сохранить, затем выполнить работу, сохранить изменения и удалить контекст.

+0

Спасибо. Это работает! – user1676605

Смежные вопросы