Идеи для повышения эффективности на тяжелом сайте данных - PullRequest
0 голосов
/ 27 января 2011

Я работаю над сайтом для клиента и пытаюсь более эффективно использовать данные о продажах. Мое оригинальное решение превратилось в спагетти-кашу с нестандартными SQL-запросами, которые кажутся слишком хакерскими. Затем я попытался написать класс-обертку (SalesCalculator), который будет обрабатывать все соответствующие записи о продажах и пытаться обработать их в Ruby, но когда мы говорим о более 30 000 записей, это сильно снижает производительность, вплоть до того, что даже кэширование потенциально раздражает (речь идет о загрузке страницы> 10 с).

Я также пытался просто создать запрос для eac

Я полагаю, что моей общей целью является упрощение взаимодействия с данными, чтобы я мог поддерживать согласованный интерфейс. Вот пара вещей, которые я обычно делаю на любой странице:

  • общий доход от продаж за каждый год в течение 3 лет
  • То же, что и выше, но разбито на 5 или около того отделов
  • общий доход по месяцам для отдела / сотрудника (за текущий и предыдущий год)
  • и т.д.

Итак, мой вопрос: какие у вас есть предложения / примеры, как делать подобные вещи с большими наборами данных?

Ответы [ 4 ]

3 голосов
/ 27 января 2011

Похоже, вы используете свою базу данных в качестве файловой системы и используете Ruby через Rails для выполнения тяжелой работы по созданию отчета - я бы вернулся к использованию SQL.

Проверьте свои запросы,и добавьте индексы в зависимости от ситуации, и вы сможете сократить время загрузки страницы.

3 голосов
/ 27 января 2011

30к это ничто.даже для базы данных SQLite.

Ваша проблема заключается в следующем: 30 000+ объектов AR повторяются как минимум 15 раз - не делайте этого.Это плохая идея и плохой дизайн, и это просто плохо со всех сторон.

у вас уже есть поле даты в вашей таблице, почему бы не использовать WHERE YEAR (date) = 2011?Вы можете добавить столбец отдела в базу данных.Вы можете добавить индекс для определенных полей, чтобы повысить производительность запросов.Вы можете сделать кучу вещей, чтобы сузить область поиска и получить только те объекты AR, которые вам действительно нужны.

загрузка всей вашей базы данных в объекты AR размером 30 тыс. - последнее, что вы хотите сделать, и я не могу представить, в чем заключается проблема, требующая такого решения.

0 голосов
/ 27 января 2011

Комбинация named_scope может быть способом, которым вы можете предоставить их с параметрами, описывающими, как вы хотите фильтровать данные (пусть база данных выполняет тяжелую работу).

Если это невозможно, всегда есть find_each(:batch => 1000), который будет одновременно захватывать 1000 записей.

0 голосов
/ 27 января 2011

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

Выполнение собственных запросов в рельсах:

class Sales

  # Other code

  def self.totals (group_by, where, ...)
    # Build the query depending of the parameters
    sql = "SELECT SUM(amount) FROM sales ... " 
    # Execute the query
    result = connection.execute(sql) 
    # when using mysql result will be a Mysql::Result object
    # Finally you can wrap the totals in a nice hash
    data = {}
    result.each_hash do |row|
      data[row['col']] = row['other_col']
    end
    data
  end

Это позволяет выполнять запросы, вызывая Sales.totals(..).

Если вы хотите сделать запрос издругой класс, просто используйте Sales.connection.execute(sql)

Mysql api: http://www.tmtm.org/en/mysql/ruby/

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