【问题标题】:Get low stock from a C# dll database which generate million rows automatically从自动生成百万行的 C# dll 数据库中获取低库存
【发布时间】:2011-11-10 02:55:19
【问题描述】:

我有一个数据库(C#,dll),它只包含一个表,自动生成百万行。

我一次只能得到一排。该表的列是:int ItemID, string category, string model, string Brand)。

如果两个项目具有相同的category, brand, model,则它们是相同的)。我想找出所有库存低的商品类型,其中低是该类型的商品剩余两个或更少。

这是我为此编写的代码,但执行需要 2 或 3 个小时,它没有给我正确的结果。我该如何解决这个问题?

   public DataTable getLowStock()
   {
       DataTable dt = new DataTable();
       object[,] arr=new object[1000000,4];
       int  index=0;
       int rows;
       rows = db.NumRows;
       int[] IdArray;
       IdArray = db.GetItemIDList(0, rows - 1);

       string Category, Brand, Model, Condition, Location, Notes;
       DateTime ReceivedDate, LastUpdated;
       int Weight;
       double PurchasePrice, SellingPrice;

       for (int a = 0; a < IdArray.Length; a++)
       {
           Console.WriteLine(a);

           db.GetItemRecord(IdArray[a], out Category, out Brand, out Model,
                            out ReceivedDate, out Weight, out Condition, out Location,
                            out PurchasePrice, out SellingPrice, out Notes, out LastUpdated);

           if (a == 0)
           {
               arr[0, 0] = Category;
               arr[0, 1] = Brand;
               arr[0, 2] = Model;
               arr[0, 3] =  1;
               index++;

           }
           else
           {

               for (int i = 0; i < index; i++)
               {

                   if ( ( arr[i,2].ToString()==Model)&& (arr[i,1].ToString()==Brand) &&   (arr[i,0].ToString()==Category ) )
                   {

                       arr[i, 3] = (Int32)arr[i, 3] + 1;
                   }
               }

               arr[index,0]=Category;
               arr[index,1]=Brand;
               arr[index,2]=Model;
               arr[index, 3] = 1;

               index++;
           }

       }

        dt.Columns.Add("Category", typeof(string));    
        dt.Columns.Add("Model", typeof(string));
        dt.Columns.Add("Brand", typeof(string));
        dt.Columns.Add("count", typeof(int));   

        for (int i = 0; i < index; i++) {
           Console.WriteLine("i="+i);

       if((int)arr[i,3]<3){
           dt.Rows.Add(arr[i,0].ToString(),arr[i,2].ToString(),arr[i,1].ToString(),(int)arr[i,3]);
       }
       }
       return dt;
   }

【问题讨论】:

  • (C#, dll) 不是真正的数据库 - 你在用什么?大概是 SQL Server - 那么问题是:为什么您将所有数据加载到您的客户端以检测重复和/或低库存?这就是数据库的用途 - 在 (SQL) 服务器上
  • 我可以通过查询轻松做到这一点,但这是一项任务。他们限制了 LINQ、绑定和数据源的使用。
  • 我非常怀疑您是否能够显着加快您的处理速度......没有“神奇”的方法可以快速做到这一点 - 如果您需要在客户端上执行此操作 - 它只是需要时间。

标签: c# string object hashtable


【解决方案1】:

当然,最好的方法是使用实​​际数据库?然后你可以在 SQL 中进行查询,它的执行速度比查询内存数据表快 1000 倍左右。

【讨论】:

    【解决方案2】:

    我建议您执行 sql 聚合并仅获取聚合,而不是获取整个表:

    SELECT category, model, brand, COUNT(*) 
    FROM table 
    GROUP BY category, model, brand
    HAVING COUNT(*) >= 2
    

    然后,您的代码很慢有几个原因,但主要原因是它是二次的。 所以 100 万平方产生 1000 亿次操作,这很慢。

    如果您必须自己进行聚合,则必须使用合适的容器,例如集合或哈希表,而不是数组。这样,您将在 O(n)(使用良好的哈希表)或 O(n log n)(使用集合)中执行,而不是 0(n^2)。

    【讨论】:

    • @marc_s,@OlivierS 非常感谢,但是使用哈希表我只能添加两对(值和键)。我已经通过连接 3 个字符串值尝试使用哈希表,但它也需要很长时间,操作后我也无法重新排序 3 个字段。
    • 您的密钥应该类似于 String.Concat(Category,'_',Model,'_',Brand) ,并且值是您找到此密钥的次数。然后输出值 >= 2 的键。显然,如果您的表有 100 万行,那么获取它们可能会很长。
    猜你喜欢
    • 1970-01-01
    • 2012-12-06
    • 2018-12-21
    • 2017-04-22
    • 2021-12-12
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多