Область ассоциации - какой лучший способ сделать это? - PullRequest
1 голос
/ 28 ноября 2011

У меня есть два способа сделать похожую вещь, и я хотел бы знать: 1. Что является менее «требовательным» к базе данных ?, 2. Что быстрее ?, 3. Что занимает меньше памяти?, И 4. Если есть какие-то другие вопросы, которые я должен учитывать при сравнении двух.

По сути, у меня есть модель событий, которая имеет множество обменов. Мне нужны обмены для события, отсортированного по типу «длинный» и «короткий». Первый способ выглядит так:

@event.exchanges.each do |ex|
  if ex.short == true
    @sells << [ex.price, ex.quantity]
  else
    @buys << [ex.price, ex.quantity]
  end
end

Другими способами является установка областей в модели Exchange для коротких и длинных типов и сортировка обменов следующим образом:

@sells = @event.exchanges.shorts
@buys = @event.exchanges.longs

Второй способ более лаконичен и удобен для чтения. Но может показаться, что ActiveRecord дважды «циклически» перебирает все обмены Я использовал первый способ, потому что хотел минимизировать время доступа Rails к базе данных. Но я могу неправильно понять, как работают базы данных. Я также (вслепую) предполагаю, что второй способ занимает больше памяти, когда вы получаете весь объект, когда мне действительно нужны два атрибута от каждого (как дает первый метод).

Я правильно понимаю или нет? Есть ли другие факторы, которые я тоже должен учитывать?

----- Отредактировано в схеме ----- Это схема для моделей Event & Exchange:

create_table "events", :force => true do |t|
  t.string   "title"
  t.text     "description"
  t.integer  "last_price"
  t.integer  "outcome"
  t.boolean  "closed"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "exchanges", :force => true do |t|
  t.integer  "event_id"
  t.integer  "user_id"
  t.integer  "price"
  t.integer  "quantity"
  t.boolean  "short"
  t.datetime "created_at"
  t.datetime "updated_at"
end

1 Ответ

1 голос
/ 28 ноября 2011

Сравнительный анализ - это единственный способ узнать наверняка, но ваш первый пример имеет рубиновый цикл по каждой строке запроса для создания двух массивов, в то время как во втором примере база данных агрегирует результаты и возвращает их за один шаг.

Вы можете использовать тестер рельсов, чтобы узнать наверняка, но мой личный инстинкт был бы для "разумных условий" (что бы это ни значило), вам было бы лучше, если бы db выполнил тяжелую работу и вместо этого получил два массива назад. позволить базе данных вернуть один массив, выполнить цикл по каждому элементу, а для каждого элемента - проверку значения и добавление массива.

...