Стремительная загрузка, генерирующая более медленные запросы - PullRequest
1 голос
/ 22 марта 2011

Я оптимизирую свое приложение и заметил кое-что интересное.Первоначально у меня было это утверждение в моем контроллере

@votes = Vote.paginate(:page => params[:page], :order=>"created_at DESC")

, и это, на мой взгляд,

<% @votes.each do |vote| %>
<tr>
  <td><%= vote.user.display_name %></td>
...

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

@votes = Vote.includes(:user).paginate(:page => params[:page],
  :order=>"created_at DESC")

При этом я заметил, что время запроса ActiveRecord для загрузки голосов / индекса удвоилось со 180 мс до 440 мс .Количество запросов было успешно сокращено при активной загрузке.Тем не менее, я нашел этот один трудоемкий запрос в ситуации активной загрузки only :

  SQL (306.5ms)  SELECT COUNT(DISTINCT "votes"."id") FROM "votes" LEFT OUTER JOIN "users" ON "users"."id" = "votes"."user_id"

Почему мой код запрашивает счетчик при левом внешнем соединении?Его нет в случае неагрессивной нагрузки.В случае неагрессивной нагрузки это самое близкое утверждение, которое я могу найти:

  SQL (30.5ms)  SELECT COUNT(*) FROM "votes"

Это что-то связано с paginate?Это какая-то комбинация двух?

1 Ответ

2 голосов
/ 22 марта 2011

Да, этот запрос создается плагином для разбивки на страницы.Этот запрос необходим для оценки общего количества страниц.

Но если вы все равно знаете количество записей (выполнив простое SELECT COUNT(*) FROM "votes" ранее), вы можете передать это число в will_paginate с опцией :total_entries!

(см. WillPaginate :: Finder :: ClassMethods для получения дополнительной информации.)

Кстати, вы создали индекс для votes.user_id?Может быть, это замедляет запрос.Мне интересно, почему предложение DISTINCT должно занимать столько времени, сколько, возможно, id уже имеет уникальное ограничение (если нет, попробуйте добавить его).

...