пробвате sql?
Ако това е само това едно изявление и причинява производствени проблеми, можете ли да пропуснете генератора на заявки само за сега? С други думи, за много кратък период, просто напишете SQL сами. Това ще ви спечели малко време.
# All on one line:
Artist.find_by_sql
"SELECT `artists`.* FROM `artists`
WHERE `artists`.`id` = #{params[:artist_id].to_i} LIMIT 1"
ARel/MySQL обяснение?
Rails може да помогне да се обясни какво се опитва да направи MySQL:
Artist.find(params[:artist_id]).explain
http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/
Може би можете да откриете някаква разлика между заявките, които са успешни спрямо неуспешни, като например как explain
използва индекси или оптимизации.
mysql2 gem?
Можете ли да опитате да промените mysql gem на mysql2 gem? Какъв неуспех получавате, когато преминете към mysql2 gem?
волатилност?
Може би има нещо друго, което променя хеша на params в движение, така че го виждате, когато го отпечатате, но то се променя до момента, в който се изпълнява заявката?
Опитайте да присвоите променливата веднага щом получите параметрите:
artist_id = params[:artist_id]
... whatever code here...
@artist = Artist.find(artist_id)
не хеш параметрите?
Написахте „Което означава, че Rails не преминава в params[:artist_id], което очевидно е в params хеша.“ Не мисля, че това е проблемът - очаквам, че виждате това, защото Rails използва "?" като контейнер за подготвено изявление.
За да разберете, изпълнете командите, предложени от @Mori, и ги сравнете; трябва да са еднакви.
Article.find(42).to_sql
Article.find(params[:artist_id]).to_sql
подготвени отчети?
Може да е проблем с кеша на подготвен отчет, когато заявката действително се изпълнява.
Ето кода, който е неуспешен-- и има голямо дебело предупреждение.
begin
stmt.execute(*binds.map { |col, val| type_cast(val, col) })
rescue Mysql::Error => e
# Older versions of MySQL leave the prepared statement in a bad
# place when an error occurs. To support older mysql versions, we
# need to close the statement and delete the statement from the
# cache.
stmt.close
@statements.delete sql
raise e
end
Опитайте да конфигурирате вашата база данни, за да изключите подготвените отчети, за да видите дали това има значение.
Във вашия ./config/database.yml
файл:
production:
adapter: mysql
prepared_statements: false
...
бъгове с подготвени отчети?
Възможно е да има проблем с това, че Rails игнорира тази настройка. Ако искате да научите много повече за него, вижте тази дискусия и корекция на грешки от Jeremey Cole и Aaron:https://github.com/rails/rails/pull/7042
Heroku може да игнорира настройката. Ето начин, по който можете да опитате да замените Heroku, като коригирате настройката на подготовленните_изявления:https://github.com /rails/rails/issues/5297
премахване на кеша на заявките?
Опитайте да премахнете ActiveRecord QueryCache, за да видите дали това има значение:
config.middleware.delete ActiveRecord::QueryCache
http://edgeguides.rubyonrails.org/configuring.html#configuring-middle
пробвате postgres?
Ако можете да опитате Postgres, това също може да го изясни. Това може да не е дългосрочно решение за вас, но би изолирало проблема в MySQL.