#ruby-on-rails-3 #postgresql
#ruby-on-rails-3 #postgresql
Вопрос:
У меня есть кодирование контроллера rails, как показано ниже:
@checked_contact_ids = @list.contacts.all(
:conditions => {
"contacts_lists.contact_id" => @list.contacts.map(amp;:id),
"contacts_lists.is_checked" => true
}
).map(amp;:id)
его эквивалент sql
SELECT *
FROM "contacts"
INNER JOIN "contacts_lists" ON "contacts".id = "contacts_lists".contact_id
WHERE ("contacts_lists".list_id = 67494 )
Выполнение этого приведенного выше запроса занимает больше времени, я хочу другой способ выполнить тот же запрос с минимальными затратами времени.
Кто-нибудь знает, пожалуйста, обратите на меня внимание или это возможно? или приведенного выше запроса достаточно для вывода?
Я жду информации……………….
Ответ №1:
Я думаю, что основная проблема с вашим исходным запросом AR заключается в том, что он вообще не выполняет никаких объединений; вы извлекаете кучу объектов из базы данных с помощью @list.contacts
, а затем отбрасываете большую часть этой работы, чтобы получить только идентификаторы.
Первым шагом было бы заменить "contacts_lists.contact_id" => @list.contacts.map(amp;:id)
на :joins => 'contact_lists'
, но вам все равно пришлось бы извлекать кучу материала из базы данных, создавать экземпляры множества объектов, а затем выбрасывать все это вместе с .map(amp;:id)
, чтобы получить только идентификационные номера.
Вы уже знаете SQL, поэтому я бы, вероятно, сразу перешел к SQL с помощью удобного метода в вашей модели списка (или что-то еще @list
есть), что-то вроде этого:
def checked_contact_ids
connection.execute(%Q{
SELECT contacts.id
FROM contacts
INNER JOIN contacts_lists ON contacts.id = contacts_lists.contact_id
WHERE contacts_lists.list_id = #{self.id}
AND contacts_lists.is_checked = 't'
}).map { |r| r['id'] }
end
И затем, в вашем контроллере:
@checked_contact_ids = @list.checked_contact_ids
Если это недостаточно быстро, тогда просмотрите свои индексы в contacts_lists
таблице.
Нет веских причин не переходить сразу к SQL, когда вы точно знаете, какие данные вам нужны, и вам это нужно быстро; просто держите SQL изолированным внутри ваших моделей, и у вас не должно возникнуть никаких проблем.