Подтвердить что ты не робот

Методы сокращения запросов к базе данных в приложении Rails

Если у вас есть приложение Rail с множеством сложных связанных моделей, какие методы вы используете для сокращения запросов к базе данных?

На самом деле, я продолжу этот вопрос немного дальше и спрошу, что вы считаете "слишком много" запросов для любой страницы?

У меня есть страница, которая, как я ожидаю, закончит попадание базы данных примерно в 20 раз на каждую загрузку страницы. Это касается, но не знаю, стоит ли мне это относиться или что я могу сделать, чтобы уменьшить нагрузку?

4b9b3361

Ответ 1

Отъезд: bullet

Это отличный способ идентифицировать n + 1 запросов и предлагает предложения по его минимизации.

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

Пока мы находимся на нем, также проверяем: rails_indexes

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

Счастливая настройка.

Ответ 2

Одной из распространенных практик является разумное использование опции include = > : association.

Например, на контроллере вы можете:

def show
    @items = Item.find(:all) 
end

... и представление show сделает что-то вроде:

<% @items.each |item| %>
    <%= item.product.title %>
<% end %>

Это создаст запрос для каждого вызова продукта. Но если вы заявляете, что ассоциация включена следующим образом, вы получаете с нетерпением загруженные ассоциации в одном запросе:

def show
    @items = Item.find(:all, :include => :product)
end

Как всегда, проверьте консоль на время запроса и т.д.

Ответ 3

Я использую: joins and: select options, если вам нужно просто отображать данные. Я нашел очень полезный named_scope, чтобы определить все возможные: join и one: select_columns named_scope. Пример

    class Activity < ActiveRecord::Base
      belongs_to :event
      belongs_to :html_template
      has_many :participants

      named_scope :join_event, :joins => :event
      named_scope :join_owner, :joins => {:event => :owner}
      named_scope :left_join_html_template, 
      :joins => "LEFT JOIN html_templates ON html_templates.id = activities.html_template_id"
      named_scope :select_columns, lambda { |columns| {:select => columns}}
      named_scope :order, lambda{ |order| {:order => order}}
end

Итак, теперь вы можете легко создавать запросы следующим образом:

columns = "activities.*,events.title,events.owner_id,owners.full_name as owner_name"
@activities = Activity.join_event.join_owner.order("date_from ASC").select_columns(columns)

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

Ответ 4

Трудно оценить предел для запросов. Это связано с концепцией/дизайном вашего приложения.

Если вам не нужно перезагружать всю страницу, я предлагаю вам рассмотреть javascript (или rjs), чтобы обновлять только нужные вам данные. Это должно быть также улучшением пользовательского интерфейса, вашим пользователям понравится!

Проверьте SQL, сгенерированный из запросов ActiveRecord. Убедитесь, что все как ожидалось.

Подумайте о денормализации своего db, чтобы повысить производительность. (будьте осторожны)

Это то, что я вижу из "кодовой стороны".