Исправление N + 1 запросов в Rails, которым нужен счетчик - PullRequest
1 голос
/ 18 сентября 2010

Я довольно новичок в оптимизации своих запросов, у меня N + 1 запрос, и, кажется, ему нужен счетчик, но я не совсем уверен, как поступить:

...
SQL (0.5ms)  SELECT COUNT(*) AS count_id FROM (SELECT 1 FROM `photos` WHERE (`photos`.attachable_id = 4864 AND `photos`.attachable_type = 'Recipe')) AS subquery
SQL (2.1ms)  SELECT COUNT(*) AS count_id FROM (SELECT 1 FROM `votes` WHERE (`votes`.voteable_id = 4864 AND `votes`.voteable_type = 'Recipe') AND (`votes`.`vote` = 1)) AS subquery
SQL (2.0ms)  SELECT COUNT(*) AS count_id FROM (SELECT 1 FROM `votes` WHERE (`votes`.voteable_id = 4864 AND `votes`.voteable_type = 'Recipe') AND (`votes`.`vote` = 0)) AS subquery
SQL (0.3ms)  SELECT COUNT(*) AS count_id FROM (SELECT 1 FROM `photos` WHERE (`photos`.attachable_id = 4865 AND `photos`.attachable_type = 'Recipe')) AS subquery
SQL (2.6ms)  SELECT COUNT(*) AS count_id FROM (SELECT 1 FROM `votes` WHERE (`votes`.voteable_id = 4865 AND `votes`.voteable_type = 'Recipe') AND (`votes`.`vote` = 1)) AS subquery
SQL (2.4ms)  SELECT COUNT(*) AS count_id FROM (SELECT 1 FROM `votes` WHERE (`votes`.voteable_id = 4865 AND `votes`.voteable_type = 'Recipe') AND (`votes`.`vote` = 0)) AS subquery
...

Итак, у меня есть две странные вещи, которые создают здесь проблему. У меня есть эта полиморфная модель vote, и мне нужно суммировать их все, и, в основном, если кто-то проголосовал против, он имеет значение 0 в столбце vote и 1, если пользователи имели отдать свой голос. Однако похоже, что он создает этот безумный запрос.

Как я мог исправить это?


Я думаю, что причина, которая вызывает это, начинается с этого метода, на мой взгляд:

<%= recipe.votes.tally %>

И вот как я подсчитываю свои голоса:

class Vote < ActiveRecord::Base

  scope :up, where(:vote => true)
  scope :down, where(:vote => false)

  def self.tally
    self.up.count - self.down.count
  end

end

Но так как я делаю это для каждого Объекта, он должен выполнять эту логику много раз, в результате мы получаем сумасшедший N + 1.

1 Ответ

1 голос
/ 19 сентября 2010

Когда вы пишете,

Я думаю, что причина, которая вызывает это, начинается с этого метода, на мой взгляд:

<% = recipe.votes.tally%>

вы можете найти больше уверенности, получив себе экземпляр рецепта в скрипте / консоли и выполнив recipe.votes.tally там

Не совсем уверен, и этонемного расплывчато, но возможно ли вам посмотреть на то, как поместить свой метод подсчета в модель рецепта?- Стефан

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