Лучшая производительность на ассоциациях - PullRequest
2 голосов
/ 04 февраля 2009

Прямо сейчас у меня есть таблица под названием Кампании, в которой много хитов, если я позвоню, скажем:

Campaign.find(30).hits

Что занимает 4 секунды или 4213 мс.

Если я позвоню вместо этого:

campaign = Campaign.find(30)
campaign.hits.count

Загружает ли он все хиты, а затем считать? Или он видит, что я считаю и избегаю загрузки всех хитов? (В настоящее время это 300 000+ строк).

Я пытаюсь найти умный способ загрузить / посчитать мои хиты. Я думаю о добавлении метода к моей модели Campaign.rb, например:

def self.total_hits
   find :first, :select => 'COUNT(id) as hits', :conditions => ["campaign_id = ?", self.id]
end

Я знаю, что запрос не будет загружаться из таблицы hits, но это всего лишь пример подсчета его по самодельному запросу, в отличие от Ruby on Rails, который делает это для меня.

Будет ли этот запрос memcache более эффективным? (У меня он работает, но, похоже, он не лучше, не быстрее, а медленнее, просто с той же скоростью.)

def self.hits
    Rails.cache.fetch("Campaign_Hits_#{self.campaign_id}", :expires_in => 40) {
      find(:first, :select => 'COUNT(id) as hits', :conditions => ["campaign_id = ?", self.campaign_id]).hits
    }
end

Любые предложения будут великолепны!

Ответы [ 2 ]

6 голосов
/ 04 февраля 2009

Как насчет:

Campaign.find(30).hits.count

Вы можете также рассмотреть возможность добавления следующего в hit.rb (при условии отношения «один ко многим» между кампаниями и попаданиями).

belongs_to :campaign, :counter_cache => true

Затем вам понадобится столбец в таблице campaigns с именем hits_count. Это позволит избежать попадания на hits в целом, если вы только получаете счет.

Вы можете проверить API на полное изложение.

1 голос
/ 04 февраля 2009

Моя ActiveRecord может быть немного ржавой, так что извините, если да, но IIRC Campaign.find(30).hits - это как минимум два отдельных запроса. Как работает Campaign.find(30, :include => [ :hits ]).hits? Это должно выполнить один запрос.

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