Оптимизация запроса PostgreSQL-8.4

#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 изолированным внутри ваших моделей, и у вас не должно возникнуть никаких проблем.