Получите небольшой запас из базы данных C # dll, которая автоматически генерирует миллионы строк - PullRequest
0 голосов
/ 04 сентября 2011

У меня есть база данных (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;
   }

Ответы [ 2 ]

1 голос
/ 04 сентября 2011

Вместо того, чтобы извлекать всю таблицу, я предлагаю вам выполнить агрегацию sql и извлечь только агрегаты:

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

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

Если вы должны выполнить агрегацию самостоятельно, вы должны использовать подходящий контейнер, такой как набор или хеш-таблицу, а не массив.Таким образом, вы будете работать в O (n) (с хорошей хэш-таблицей) или O (n log n) (с набором) вместо 0 (n ^ 2).

1 голос
/ 04 сентября 2011

Конечно, лучший способ сделать это с реальной базой данных?Затем вы можете выполнить запрос в SQL, который будет выполняться примерно в 1000 раз быстрее, чем запрашивать данные в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...