Включая оптимизацию ассоциаций в Rails - PullRequest
0 голосов
/ 14 апреля 2010

Я ищу помощь по оптимизации Ruby для загрузки ассоциаций по требованию.

Это упрощенный пример. У меня 3 модели: Post, Comment, User. Ссылки: Post имеет много комментариев, а Comment имеет ссылку на User (: автор). Теперь, когда я перехожу на страницу поста, я ожидаю увидеть тело поста + все комментарии (и имена их авторов). Для этого необходимо выполнить 2 запроса:

select * from Post -- to get post data (1 row)
select * from Comment inner join User -- to get comment + usernames (N rows)

В коде у меня есть:

Post.find(params[:id], :include => { :comments => [:author] }

Но это работает не так, как ожидалось: как я вижу на заднем плане, все еще есть N + 1 попадания (хотя некоторые из них кэшируются). Как я могу оптимизировать это?

UPD После некоторого исследования кажется, что код был верным, но он не работает должным образом в случае, если я назвал own_to в модели Comment. После того, как я изменил с: author на: user, все заработало как положено.

Ответы [ 2 ]

1 голос
/ 14 апреля 2010

В моем проекте мои отношения аналогичны вашим Post, Comment и User моделям. Я вижу только три фактических запроса sql.

Post.find(1, :include => { :comments => [:author] })

Из журнала отладки показаны эти три запроса

SELECT * FROM `posts` WHERE (`posts`.`id` = 1)
SELECT `comments`.* FROM `comments` WHERE (`comments`.`post_id` = 1)
SELECT * FROM `authors` WHERE (`authors`.`id` IN (4,8,15,16,23,42)) 
1 голос
/ 14 апреля 2010

Если вас устраивает 2/3 запросов, вы можете попробовать:

@post = Post.find params[:id]
@comments = Comments.find_by_post_id(params[:id], :include => [:author])

или

@comments = @post.comments(:include => [:author])

Редактировать: Вы пробовали с:

Post.find (params [: id],: include => {: comments =>: author}

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