2

我有一个相当密集的方法来处理相当大批量的事情。这取决于 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 版本中,代码是从延迟作业运行的,而在 Rails 3 中,它是在正常的浏览器请求期间处理的。

有没有我错过的设置或什么?

4

1 回答 1

2

我想到了。SqlCache 是通过 Rails 中的中间件使用的:use ActiveRecord::QueryCache 这意味着它是 ActionController,它用缓存毯包装了动作处理。显然在延迟的工作中没有 ActionController 也没有缓存。恢复缓存所需要做的就是:

def method_ran_by_delayed_job
  ActiveRecord::Base.cache do
    # all your crazy code
  end
end
于 2013-09-10T16:00:09.467 回答