Низкая производительность Ruby on Rails при использовании вложенных файлов: include - PullRequest
1 голос
/ 18 марта 2010

У меня есть три модели, которые выглядят примерно так:

class Bucket < ActiveRecord::Base
  has_many :entries
end

class Entry < ActiveRecord::Base
  belongs_to :submission
  belongs_to :bucket
end

class Submission < ActiveRecord::Base
  has_many :entries
  belongs_to :user
end

class User < ActiveRecord::Base
   has_many :submissions
end

Когда я получаю коллекцию записей, делая что-то вроде:

@entries = Entry.find(:all,
                      :conditions => ['entries.bucket_id = ?', @bucket],
                      :include    => :submission)

Производительность довольно быстрая, хотя я получаю большое количество дополнительных запросов, потому что представление использует объект Submission.user. Однако, если я добавлю пользователя в оператор: include, производительность станет ужасной, и потребуется более минуты, чтобы вернуть в общей сложности 50 записей и заявок, распределенных по 5 пользователям. Когда я запускаю соответствующие команды SQL, они выполняются менее чем за секунду - производительность запросов SQL одинакова для каждого набора запросов.

@entries = Entry.find(:all,
                      :conditions => ['entries.bucket_id = ?', @bucket],
                      :include    => {:submission => :user})

Почему эта вторая команда имеет такую ​​ужасную производительность по сравнению с первой?

Ответы [ 3 ]

0 голосов
/ 18 марта 2010

Я не уверен, будет ли производительность намного лучше, но попробуйте:

@bucket.entries.find(:all, :include => {:submission => :user})

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

def self.up
  create_table :entries do |t|
    t.references :submission 
    t.references :bucket
    # other fields...
  end

  add_index :entries, :submission_id
  add_index :entries, :bucket_id
end
0 голосов
/ 19 марта 2010

В результате возникла проблема с сериализацией / десериализацией пользовательской модели во всем объектном графе. Кэшируя соответствующие данные в моделях Entry и Submission, мы смогли избежать поиска пользователя и сэкономили значительное количество времени.

0 голосов
/ 18 марта 2010

это потому, что у вас есть двойное соединение во втором утверждении. Таким образом, число результатов больше.

Чем больше, тем медленнее результат.

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