如何优化数据库到集合转换的运行时?

时间:2011-04-19 15:45:59

标签: c# performance collections loops

我有一个数据库,我必须通过odbc连接。

数据提取需要app。 2分钟。结果DataTable有350000条记录。

我正在尝试将数据表转换为此对象图。结果集没有主键,主键是通过我从中获取数据的视图指定的。

public class PriceCurve
{
    public PriceCurve(DataTable dt)
    {
        this.Id = int.Parse(dt.AsEnumerable().First()["ID"].ToString());
        this.Prices = new List<Price>();
        GetPrices(dt);
    }

    public int Id { get; private set; }
    public IList<Price> Prices { get; set; }

    private void GetPrices(DataTable dt)
    {
        foreach (DataColumn column in dt.Columns)
        {
            switch (this.GetPriceProviderType(column)) // parses ColumnName to Enum
            {
                case Price.PriceProvider.A:
                    {
                        this.Prices.Add(new Price(Price.PriceProvider.A, dt.AsEnumerable()));
                    }

                    break;
                case Price.PriceProvider.B:
                    {
                        this.Prices.Add(new Price(Price.PriceProvider.B, dt.AsEnumerable()));
                    }

                    break;
            }
        }

    public class Price
    {
        public enum PriceProvider
        {
            A, B
        }

        public Price(PriceProvider type, IEnumerable<DataRow> dt)
        {
            this.Type = type;
            this.TradingDates = new List<TradingDate>();
            this.GetTradingDates(type, dt);
        }

        public IList<TradingDate> TradingDates { get; set; }
        public PriceProvider Type { get; set; }

        private void GetTradingDates(PriceProvider type, IEnumerable<DataRow> dt)
        {
            var data = dt.Select(column => column["TRADING_DATE"]).Distinct();

            foreach (var date in data)
            {
                this.TradingDates.Add(new TradingDate(date.ToString(), type, dt));
            }
        }

        public class TradingDate
        {
            public TradingDate(string id, PriceProvider type, IEnumerable<DataRow> dt)
            {
                this.Id = id;
                this.DeliveryPeriodValues = new Dictionary<int, double?>();
                this.GetDeliveryPeriodValues(type, dt);
            }

            public string Id { get; set; }
            public IDictionary<int, double?> DeliveryPeriodValues { get; set; }

            private void GetDeliveryPeriodValues(PriceProvider type, IEnumerable<DataRow> dt)
            {

                foreach (var row in dt.Where(column => column["TRADING_DATE"].ToString() == this.Name))
                {
                    try
                    {
                        this.DeliveryPeriodValues.Add(
                            int.Parse(row["DELIVERY_PERIOD"].ToString()),
                            double.Parse(row[Enum.GetName(typeof(Price.PriceProvider), type)].ToString()));
                    }
                    catch (FormatException e)
                    {
                        this.DeliveryPeriodValues.Add(
                            int.Parse(row["DELIVERY_PERIOD"].ToString()),
                            null);
                    }
                }    
            }
        }
    }

我创建了一个对象,其中包含一个包含两个对象的列表。这两个对象中的每一个都包含一个包含1000个对象的列表这1000个对象中的每一个都包含350对的字典。

它会在调试期间崩溃visual studio 2010,因OutOfMemory而失败或需要几分钟(不可接受)才能执行。

解决此问题的最佳方法是什么。我是c#的新手,不知道如何通过这个庞大的数据或我的对象图来优化循环。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

  

它会在调试期间崩溃visual studio 2010,因为OutOfMemory失败或需要几分钟   (不可接受)执行。

你让我开怀大笑。真。

  • 在使用.NET的32位计算机上,350.000个节点面临挑战。添加一些开销,你就死定了。使用对象,而不是非常破坏内存的adata表。

  • 花费几分钟几乎是你的决定/编程。使用对象列表,而不是数据表。使用分析器。让初学者犯错误:

  

var data = dt.Select(column =&gt; column [“TRADING_DATE”])。Distinct();

不需要,稍后在代码中处理双打。区别很贵。简介。

  

foreach(dt.Where中的var行(列=&gt;列[“TRADING_DATE”]。ToString()== this.Name))

这是350.000行按名称查找以获取列的索引,并通过大量的tostring进行比较。

获取一个分析器,找出您的确切花费时间的位置。请摆脱表格并使用对象 - 与对象列表相比,DataTable是一个内存耗尽和SLOW。是的,这需要几分钟。主要原因:

  • 你的节目。不是一种耻辱。刚刚学习,现在就去对象/结构。
  • ODBC。花时间加载数据,特别是当你不处理swhile加载(DataReader)但是等待加载所有加载,并且ODBC不快。 350.000行,良好的网络,直接的SQL Server可能是30秒 - 相同的机器少。