我有一个相当密集的方法来处理相当大批量的东西。这取决于 ActiveRecord 在无数次使用完全相同的查询访问数据库时是否保守。
这就是我在 Rails 3 中所拥有的:
CACHE (0.0ms) SELECT `song_work_numbers`.* FROM `song_work_numbers` ...
CACHE (0.0ms) SELECT `variance_statement_line_matches`.* FROM `variance_statement_line_matches` ...
CACHE (0.0ms) SELECT `songs`.* FROM `songs` ...
CACHE (0.0ms) SELECT `variance_statement_line_matches`.* ...
CACHE (0.0ms) SELECT COUNT(*) FROM `productions` ...
CACHE (0.0ms) SELECT `productions`.* FROM `productions` ...
ProductionWorkNumber Load (0.6ms) SELECT `production_work_numbers`.* FROM `production_work_numbers` ...
SQL (0.4ms) SELECT COUNT(*) FROM `production_episodes` ...
ProductionEpisode Load (0.4ms) SELECT `production_episodes`.* FROM `production_episodes` ...
Processed Line [449] in 0.010037 s
CACHE (0.0ms) SELECT `song_work_numbers`.* FROM `song_work_numbers` ...
CACHE (0.0ms) SELECT `variance_statement_line_matches`.* FROM `variance_statement_line_matches` ...
CACHE (0.0ms) SELECT `songs`.* FROM `songs` ...
CACHE (0.0ms) SELECT `production_work_numbers`.* FROM `production_work_numbers` ...
CACHE (0.0ms) SELECT `variance_statement_line_matches`.* FROM `variance_statement_line_matches` ...
CACHE (0.0ms) SELECT COUNT(*) FROM `productions` ...
CACHE (0.0ms) SELECT `productions`.* FROM `productions` ...
CACHE (0.0ms) SELECT `production_work_numbers`.* FROM `production_work_numbers` ...
CACHE (0.0ms) SELECT COUNT(*) FROM `production_episodes` ...
CACHE (0.0ms) SELECT `production_episodes`.* FROM `production_episodes` ...
Processed Line [450] in 0.006033 s
这就是我在 Rails 4 中得到的
SongWorkNumber Load (1.5ms) SELECT `song_work_numbers`.* FROM `song_work_numbers` ...
Variance::StatementLineMatch Load (0.4ms) SELECT `variance_statement_line_matches`.* FROM `variance_statement_line_matches` ...
Song Load (0.5ms) SELECT `songs`.* FROM `songs` ...
ProductionWorkNumber Load (1.9ms) SELECT `production_work_numbers`.* FROM `production_work_numbers` ...
Variance::StatementLineMatch Load (0.9ms) SELECT `variance_statement_line_matches`.* FROM `variance_statement_line_matches` ...
(2.9ms) SELECT COUNT(*) FROM `productions` ...
Production Load (1.5ms) SELECT `productions`.* FROM `productions` ...
ProductionWorkNumber Load (1.7ms) SELECT `production_work_numbers`.* FROM `production_work_numbers` ...
(0.6ms) SELECT COUNT(*) FROM `production_episodes` ...
ProductionEpisode Load (112.2ms) SELECT `production_episodes`.* FROM `production_episodes` ...
[Processed line 449 in 0.137435 sec]
SongWorkNumber Load (1.5ms) SELECT `song_work_numbers`.* FROM `song_work_numbers` ...
Variance::StatementLineMatch Load (0.4ms) SELECT `variance_statement_line_matches`.* FROM `variance_statement_line_matches` ...
Song Load (0.5ms) SELECT `songs`.* FROM `songs` ...
ProductionWorkNumber Load (1.7ms) SELECT `production_work_numbers`.* FROM `production_work_numbers` ...
Variance::StatementLineMatch Load (0.4ms) SELECT `variance_statement_line_matches`.* FROM `variance_statement_line_matches` ...
(0.5ms) SELECT COUNT(*) FROM `productions` ...
Production Load (1.5ms) SELECT `productions`.* FROM `productions` ...
ProductionWorkNumber Load (1.9ms) SELECT `production_work_numbers`.* FROM `production_work_numbers` ...
(0.6ms) SELECT COUNT(*) FROM `production_episodes` WHERE ...
ProductionEpisode Load (0.5ms) SELECT `production_episodes`.* FROM `production_episodes` ...
[Processed line 450 in 0.023306 sec]
如您所见,这要慢得多。当超过 50K 行时,这些毫秒确实会增加。
查询是相同的。代码是一样的。唯一的区别是,在 Rails 4 版本中,代码是从elasted_job 运行的,而在 Rails 3 中,代码是在正常浏览器请求期间处理的。
是否有我错过的设置或其他内容?
最佳答案
我明白了。 SqlCache 通过 Rails 中的中间件使用:use ActiveRecord::QueryCache
这意味着 ActionController 用缓存覆盖层包装了 Action 处理。显然,在延迟作业中没有 ActionController,也没有缓存。要恢复缓存,您所需要做的就是:
def method_ran_by_delayed_job
ActiveRecord::Base.cache do
# all your crazy code
end
end
关于ruby-on-rails - 从 Rails 3 迁移到 Rails 4 导致自动 ActiveRecord 缓存丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18720355/