У нас есть приложение 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 в порядке.
Я считаю, что он не кэшируется по двум причинам:
- Нет выбирает с производственным журналом (в режиме отладки) показать CACHE
префикс - просто идентичные SELECT с очень немного отличающимися временными метками XX.XXms; и
- Включение
аудит базы данных с 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]]