Несколько расчетов на одном наборе данных: рубин или база данных? - PullRequest
3 голосов
/ 25 декабря 2010

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

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

data[:total_before] = Transaction.where(xxx).sum(:amount_before)
data[:total_after] = Transaction.where(xxx).sum(:amount_after)
...

или

transactions = Transaction.where(xxx)
data[:total_before]= transactions.inject(0) {|s, e| s + e.amount_before }
data[:total_after]= transactions.inject(0) {|s, e| s + e.amount_after }
...

edit: предложение where всегда одинаковое.

Какой из них выбрать? (или есть третий, лучший способ?)

Спасибо, П.

Ответы [ 2 ]

4 голосов
/ 25 декабря 2010

На самом деле вы говорите о масштабируемости.

Если вы говорите о миллионах строк и нуждаетесь в их вычислениях, то как вы думаете, что будет быстрее?

  1. Запрос DBM суммировать миллионы строк и вернуть вам два числа.
  2. Возвращать миллионы результатов запроса по сети, которые вы повторяете дважды.

В первом сценарии вы можете увеличить ваш хост БД с более быстрыми процессорами, большим объемом ОЗУ, более быстрыми дисками или предварительно вычислить значения через равные промежутки времени.Вычисления, которые вы хотите выполнить в DBM, - это как раз то, для чего они написаны.

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

Я бы сделал первый, поскольку он кажется мне гораздо более масштабируемым.

4 голосов
/ 25 декабря 2010

Не ворчать, а как насчет

transactions = Transaction.where(xxx)
data[:total_before] = transactions.sum(:amount_before)
data[:total_after] = transactions.sum(:amount_before)

?Это похоже на объединение сильных сторон методов 1 и 2 :). Вы повторно используете результаты поиска и используете более чистый специфичный для рельсов агрегатор sum.

PS Если вы спрашивали, можно ли полагаться на Rails при кэшировании результатов запроса Transaction.where(xxx), я не знаю.А когда я не знаю, я предпочитаю играть безопасно.

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