首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails Memoization on a有很多关系

Rails Memoization on a有很多关系
EN

Stack Overflow用户
提问于 2018-10-14 04:24:23
回答 2查看 357关注 0票数 0

是否可以通过对包含has_many关联的SQL查询执行内存操作来缓存实例变量?在下面的两个示例方法中,some_instance方法将按照预期进行缓存,但some_other_instance将缓存Artist而不是歌曲关联,这将导致每次运行该方法时都会产生一个SQL查询。

似乎当方法返回"ActiveRecord::Associations::CollectionProxy“或"ActiveRecord::Relation”时,它不会完全缓存。

代码语言:javascript
复制
class Artist < ApplicationRecord
    has_many :artist_songs
    has_many :songs, through: :artist_songs

    def self.some_instance
        @some_instance ||= find(10)
    end

    def self.some_other_instance
        @some_other_instance ||= find(10).songs
    end
end
EN

回答 2

Stack Overflow用户

发布于 2018-10-14 17:06:16

some_instance方法缓存find(10)方法的结果,该方法执行DB query并返回一条记录。

但是some_other_instance方法缓存的是关系对象,而不是DB查询的结果。实际上,如果您在像Artist.some_other_instance;这样的rails控制台中运行(注意,在的末尾是),就不会有任何DB查询,因为您没有使用查询的结果。但是,当您只运行Artist.some_other_instance时,将会出现查询,因为结果是用来打印的。

因此,要真正缓存some_other_instance方法,您需要添加类似to_a的内容,例如:

def self.some_other_instance @some_other_instance ||= find(10).songs.to_a end

但在这种情况下,此方法将不是“可链接的”。

票数 0
EN

Stack Overflow用户

发布于 2018-10-15 09:40:30

to_a提供了缓存关系的解决方案。

在下面的日志中,SQL查询耗时1883.4ms,构建视图耗时623.4ms。总时间是15053ms,这意味着在对象上添加to_a需要12546.2ms。如果我关闭to_a,总时间会降到2000ms左右。

构建对象需要这么长时间,这正常吗?

代码语言:javascript
复制
Started GET "/build" for 127.0.0.1 at 2018-10-14 16:35:30 -0700
Processing by ArtistsController#build as HTML
  Artist Load (208.4ms)  SELECT `artists`.`id`, `artists`.`name`, `artists`.`uri`, `artists`.`artwork_url`, updates.popularity, updates.created_at AS pop_created_at, reachupdates.reach, reachupdates.created_at AS reach_created_at FROM `artists` INNER JOIN `updates` ON `updates`.`artist_id` = `artists`.`id` INNER JOIN `reachupdates` ON `reachupdates`.`artist_id` = `artists`.`id` WHERE `artists`.`id` = 1
  Song Load (510.5ms)  SELECT songs.*, songupdates.* FROM `songs` INNER JOIN `artist_songs` ON `artist_songs`.`song_id` = `songs`.`id` INNER JOIN `artists` ON `artists`.`id` = `artist_songs`.`artist_id` INNER JOIN `songupdates` ON `songupdates`.`song_id` = `songs`.`id` WHERE `artists`.`id` = 1
  Playlist Load (1089.2ms)  SELECT playlists.*, playlistupdates.* FROM `playlists` INNER JOIN `playlist_songs` ON `playlist_songs`.`playlist_id` = `playlists`.`id` INNER JOIN `songs` ON `songs`.`id` = `playlist_songs`.`song_id` INNER JOIN `playlistupdates` ON `playlistupdates`.`playlist_id` = `playlists`.`id` LEFT OUTER JOIN `artist_songs` ON `artist_songs`.`song_id` = `songs`.`id` LEFT OUTER JOIN `artists` ON `artists`.`id` = `artist_songs`.`artist_id` WHERE `artists`.`id` = 1 AND `playlists`.`relevant` = 1 AND (playlistupdates.id IN (SELECT MAX(playlistupdates.id) AS id FROM playlistupdates GROUP BY playlistupdates.playlist_id)) ORDER BY `playlistupdates`.`followers` DESC
  Rendering artists/build.html.haml within layouts/application
  Rendered artists/build.html.haml within layouts/application (15.6ms)
  Rendered layouts/_head.html.haml (45.8ms)
  Rendered svg/_settings.html.erb (0.9ms)
  Rendered svg/_search.html.erb (0.4ms)
  Rendered layouts/_header_new.html.haml (73.3ms)
  Rendered shared/_autocomplete-box.html.haml (14.2ms)
Completed 200 OK in 15053ms (Views: 623.4ms | ActiveRecord: 1883.4ms)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52797006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档