На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Оптимизация выборки данных , SQL, C#
    Цитата nvn @

    Что подразумевается под array я не знаю. Единственное, что известно, это тип данных string.
    Скорее всего, параметры считываются из текстового файла.
    Например, отрывок из книги разбивается на слова, и из базы вытаскиваются определения для этих слов.
    Сообщение отредактировано: cyt -
      тогда возможно стоит подумать о том чтобы немного поменять вызов БД - вам ведь наверняка хочется чтобы результат работы видел пользователь - сделайте фоновый поток который колбасит один элемент - открывает и закрывает connection читает результат и выплёвывает его обратно в поток интерфейса, а сам берёт следующий элемент и т.д.
        Нет, мне это не нужно. Главное, чтобы скорость работы увеличилась.
          А если ваш код переделать как то так
          ExpandedWrap disabled
            static void Main(string[] args)
                    {
                        
                        string[] array = new string[10004]; // Некий массив, длина которого может достигать >10000
             
                        for (int i = 0; i < array.Length; i++)
                        {
                            array[i] = i.ToString();
                        }
             
                        int count = array.Length/100;
                        int ost = array.Length%100;
             
                        string format = string.Empty;
                        if (count > 0)
                        {
                            for (int i = 0; i < count; i++)
                            {
                                int start = i * count;
                                int end = (i + 1)*count;
             
                                if(end > array.Length)
                                    break;
             
                                format = string.Format("'{0}'", array[start]);
                                for (int j = start + 1; j < end; j++)
                                {
                                    format += "," + string.Format("'{0}'", array[j]);
                                }
                                string commandString = string.Format("SELECT [ID] FROM [Table] WHERE [Param] IN ({0})", format);
             
                                GetValue(commandString);
                            }
                            if (ost > 0)
                            {
                                format = string.Format("'{0}'", array[array.Length - 1 - ost]);
                                if (ost > 1)
                                {
                                    for (int i = array.Length - ost; i < array.Length; i++)
                                    {
             
                                        format += "," + string.Format("'{0}'", array[i]);
                                    }
                                }
                                string commandString = string.Format("SELECT [ID] FROM [Table] WHERE [Param] IN ({0})", format);
             
                                GetValue(commandString);
                            }
                        }
                        else
                        {
                            format = string.Format("'{0}'", array[0]);
                            for (int i = 1; i < array.Length; i++)
                            {
                                format += "," + string.Format("'{0}'", array[i]);
                            }
                            string commandString = string.Format("SELECT [ID] FROM [Table] WHERE [Param] IN ({0})", format);
             
                            GetValue(commandString);
                        }
                    }
             
                    private static void GetValue(string commandString)
                    {
                        SqlCommand command = new SqlCommand("", new SqlConnection());
                        SqlDataReader reader;
                        command.CommandText = commandString;
                        reader = command.ExecuteReader();
                    }
          Или чтобы не писать всю эту лабуду. Использовать TakeWhile.
            извините крик души :) я всё таки хочу сказать вот - что скорее всего ваш массив со словами содержит уникальных не так много строк тут например написано что сочинения Пушкина содержат 24 тысячи разных слов, вы уверены что не надо думать в сторону оптимизации логики, а сосредоточится только на оптимизации этого запроса?
              Цитата nvn @
              извините крик души :) я всё таки хочу сказать вот - что скорее всего ваш массив со словами содержит уникальных не так много строк тут например написано что сочинения Пушкина содержат 24 тысячи разных слов, вы уверены что не надо думать в сторону оптимизации логики, а сосредоточится только на оптимизации этого запроса?

              Да, уверен :) Это экспериментальная задача.
              В таком виде, конечно, она никуда внедряться не будет.
              Интерес уже почти просто спортивный.

              Добавлено
              Цитата Craft @
              А если ваш код переделать как то так
              ExpandedWrap disabled
                static void Main(string[] args)
                        {
                            
                            string[] array = new string[10004]; // Некий массив, длина которого может достигать >10000
                 
                            for (int i = 0; i < array.Length; i++)
                            {
                                array[i] = i.ToString();
                            }
                 
                            int count = array.Length/100;
                            int ost = array.Length%100;
                 
                            string format = string.Empty;
                            if (count > 0)
                            {
                                for (int i = 0; i < count; i++)
                                {
                                    int start = i * count;
                                    int end = (i + 1)*count;
                 
                                    if(end > array.Length)
                                        break;
                 
                                    format = string.Format("'{0}'", array[start]);
                                    for (int j = start + 1; j < end; j++)
                                    {
                                        format += "," + string.Format("'{0}'", array[j]);
                                    }
                                    string commandString = string.Format("SELECT [ID] FROM [Table] WHERE [Param] IN ({0})", format);
                 
                                    GetValue(commandString);
                                }
                                if (ost > 0)
                                {
                                    format = string.Format("'{0}'", array[array.Length - 1 - ost]);
                                    if (ost > 1)
                                    {
                                        for (int i = array.Length - ost; i < array.Length; i++)
                                        {
                 
                                            format += "," + string.Format("'{0}'", array[i]);
                                        }
                                    }
                                    string commandString = string.Format("SELECT [ID] FROM [Table] WHERE [Param] IN ({0})", format);
                 
                                    GetValue(commandString);
                                }
                            }
                            else
                            {
                                format = string.Format("'{0}'", array[0]);
                                for (int i = 1; i < array.Length; i++)
                                {
                                    format += "," + string.Format("'{0}'", array[i]);
                                }
                                string commandString = string.Format("SELECT [ID] FROM [Table] WHERE [Param] IN ({0})", format);
                 
                                GetValue(commandString);
                            }
                        }
                 
                        private static void GetValue(string commandString)
                        {
                            SqlCommand command = new SqlCommand("", new SqlConnection());
                            SqlDataReader reader;
                            command.CommandText = commandString;
                            reader = command.ExecuteReader();
                        }
              Или чтобы не писать всю эту лабуду. Использовать TakeWhile.

              Если можно, в двух словах, что вы написали?
                Цитата cyt @
                Если можно, в двух словах, что вы написали?

                Выборка пачками по 100 записей где то для 10000. Сначала выбираю от 0 записи по 100, формирую запрос в таком виде
                ExpandedWrap disabled
                  SELECT [ID] FROM [Table] WHERE [Param] IN ('param1', 'param2')
                где param1, param2 элементы массива array. В принципе ничего сложного.
                ExpandedWrap disabled
                  if (ost > 0)
                                  {
                                      format = string.Format("'{0}'", array[array.Length - 1 - ost]);
                                      if (ost > 1)
                                      {
                                          for (int i = array.Length - ost; i < array.Length; i++)
                                          {
                   
                                              format += "," + string.Format("'{0}'", array[i]);
                                          }
                                      }
                  }
                Беру остаток от того что осталось и собираю запрос из него. Например у вас 10004 элемента в массиве. Деление на 100 даст вам выборку до 1000. То есть вы 1К раз вызовете ваш запрос к базе для каждых 100 элементов. Обычный цикл. Деление 10004 на 100 даст 4 в остатке, которые тоже нужно учесть для отбора значений с БД. Код я написал исходя из примера в вашем первом посте.
                  Цитата Craft @
                  Цитата cyt @
                  Если можно, в двух словах, что вы написали?

                  Выборка пачками по 100 записей где то для 10000. Сначала выбираю от 0 записи по 100, формирую запрос в таком виде
                  ExpandedWrap disabled
                    SELECT [ID] FROM [Table] WHERE [Param] IN ('param1', 'param2')
                  где param1, param2 элементы массива array. В принципе ничего сложного.
                  ExpandedWrap disabled
                    if (ost > 0)
                                    {
                                        format = string.Format("'{0}'", array[array.Length - 1 - ost]);
                                        if (ost > 1)
                                        {
                                            for (int i = array.Length - ost; i < array.Length; i++)
                                            {
                     
                                                format += "," + string.Format("'{0}'", array[i]);
                                            }
                                        }
                    }
                  Беру остаток от того что осталось и собираю запрос из него. Например у вас 10004 элемента в массиве. Деление на 100 даст вам выборку до 1000. То есть вы 1К раз вызовете ваш запрос к базе для каждых 100 элементов. Обычный цикл. Деление 10004 на 100 даст 4 в остатке, которые тоже нужно учесть для отбора значений с БД. Код я написал исходя из примера в вашем первом посте.

                  Спасибо, попробую. Думаю вам уже самим интересно, что из этого выйдет ;) Отпишусь.
                    конечно уже интересно, хотя странно что программа виснет при таком размере sql текста, обычный ms sql поддерживает запросы весом около 250 метров (по крайней мере люди так по всему инету пишут)
                      Подходящим оказался вариант с предварительной выборкой Param:
                      ExpandedWrap disabled
                        command.CommandText = "SELECT DISTINCT Param FROM Table";
                                    reader = command.ExecuteReader();
                                    while (reader.Read())
                                        temp.Add(reader.GetString(0));
                                    reader.Close();

                      Затем значения массива array сравниваются со значениями массива temp.
                      Если есть совпадение array[i] с каким-нибудь значением массива temp, делается необходимая выборка.
                      Так как вероятность полного вхождения массива array в массив temp отсутствует (вхождение составляет около 10%),
                      нагрузка на базу резко снизилась.

                      P.S. Вариант с группировкой дал прирост, но значительно меньший. Тем не менее, при других условиях (если бы вхождение
                      могло достигать 100%) он мог бы очень пригодиться. Всем спасибо!
                      Сообщение отредактировано: cyt -
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0400 ]   [ 16 queries used ]   [ Generated: 1.05.24, 10:50 GMT ]