Как исправить медленный неявный запрос в таблице pg_attribute в Rails

В нашей производственной среде мы заметили частые всплески (~ каждые 1 час) в нашем Rails-приложении. Копая глубже, это связано с следующим запросом, который кумулятивно работает в > 1,5 с (называется 100х) в одном HTTP-запросе.

SELECT a.attname, format_type(a.atttypid, a.atttypmod), pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = ?::regclass AND a.attnum > ? AND NOT a.attisdropped 
ORDER BY a.attnum

У нас нет кода, вызывающего эту таблицу явно, но, по-видимому, он вызвал Rails для определения атрибутов для каждой модели. "Непредвиденные SQL-запросы к базе данных Postgres на Rails/Heroku" связан.

Но не следует ли это называть Runtime неповторимым?

Как мы ускоряем это?

Ответы

Ответ 1

Мы ускоряем это под термином, называемым нетерпеливой нагрузкой. Метод активной записи eager_load позволяет нам не выполнять запрос N + 1 для каждой строки в вашей таблице. В противном случае рельсы не знают, что вы делаете, и по умолчанию используется отдельный SELECT/JOIN для каждого атрибута, который вы хотите, который находится не в той же таблице.

Надеюсь, это поможет!!!

Ответ 2

Я не сталкивался с этой проблемой в любом Rails-приложении, с которым я работал до сих пор. Я думаю, ваше решение состоит в том, чтобы добавить active-record-query-trace в свой проект и проверить, что вызывает этот запрос.

На работе я использую эту настройку:

# Gemfile
group :test, :development do
  gem "active-record-query-trace"
end

# config/initializers/ar_tracer.rb
if ENV.has_key?("AR_TRACER") && defined? ActiveRecordQueryTrace
  ActiveRecordQueryTrace.enabled = true
  ActiveRecordQueryTrace.lines = 20 # you may want to increase if not enough
end

Затем просто запустите сервер рельсов следующим образом: AR_TRACER=1 bundle exec rails s.