Rails QueryCache включен, но не работает - PullRequest
1 голос
/ 08 июля 2019

У нас есть приложение Rails 4.2, работающее на сервере Oracle, с memcached / Dalli в качестве хранилища кеша.

Похоже, что QueryCache не работает для повторного SQL в рамках одного и того же запроса. Согласно документации:

Кэширование запросов - это функция Rails, которая кэширует возвращаемый набор результатов. по каждому запросу. Если Rails встречает тот же запрос снова для этого запрос, он будет использовать кэшированный результирующий набор в отличие от запуска запрос к базе данных снова.

Конфигурация в application / production.rb устанавливает хранилище кэша в Dalli и переключает query_cache в true в производственной среде:

application.rb: config.cache_store  = :dalli_store, 'localhost:11211', { namespace: 'BASE', down_retry_delay: 120 }

environments/production.rb:  config.action_controller.perform_caching = true

Запустив memcached в подробном режиме, я могу видеть все выборки и наборы и пропуски из нашего явного низкоуровневого кэширования (то есть Rails.cache.set), но нет доказательств какого-либо кэширования запросов. (Хотя я не уверен на 100%, должен ли кеш запросов достигать memcached или он просто хранится в памяти на время запроса). Учитывая то, что в memcached я вижу другие операции кэширования, я вполне уверен, что соединение / настройка между memcached и rails в порядке.

Я считаю, что он не кэшируется по двум причинам:

  1. Нет выбирает с производственным журналом (в режиме отладки) показать CACHE префикс - просто идентичные SELECT с очень немного отличающимися временными метками XX.XXms; и
  2. Включение аудит базы данных с Oracle показывает десятки идентичных SELECTS в запрос (т. е. идентичные условия запроса SELECT с одинаковым регистром и одинаковыми параметрами связывания)

Одно из предложений, которое я видел, это посмотреть на Middleware, чтобы убедиться, что QueryCache присутствует, что, по-видимому, выглядит так:

dave@test:~/code/app1$ rake middleware
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware>
use ActiveRecord::QueryCache

Другим предложением было проверить (и установить) ActiveRecord::Base.connection.query_cache_enabled явно. Я поместил это в before_filter для метода, который я сейчас пытаюсь оптимизировать, и он сообщает о том, что он включен, но все еще не кэшируется:

  def enable_qcache
     ActiveRecord::Base.connection.enable_query_cache!
     logger.error "IS CACHE ENABLED:  #{ ActiveRecord::Base.connection.query_cache_enabled}"
  end

   production.log: IS CACHE ENABLED:  true

Вот пример идентичного выбора в том же запросе из журнала:

  Policy Load (12.2ms)  SELECT * FROM (SELECT  "POLICY".* FROM "POLICY" WHERE "POLICY"."POLICY_ID" = :a1  ORDER BY policy_original_number DESC, policy_id DESC ) WHERE ROWNUM <= 1  [["policy_id", 459723071]]
  Policy Load (11.5ms)  SELECT * FROM (SELECT  "POLICY".* FROM "POLICY" WHERE "POLICY"."POLICY_ID" = :a1  ORDER BY policy_original_number DESC, policy_id DESC ) WHERE ROWNUM <= 1  [["policy_id", 459723071]]
  Policy Load (9.0ms)   SELECT * FROM (SELECT  "POLICY".* FROM "POLICY" WHERE "POLICY"."POLICY_ID" = :a1  ORDER BY policy_original_number DESC, policy_id DESC ) WHERE ROWNUM <= 1  [["policy_id", 459723071]]
...