essayer sql ?
S'il ne s'agit que de cette seule instruction et qu'elle cause des problèmes de production, pouvez-vous omettre le générateur de requêtes pour le moment ? En d'autres termes, à très court terme, écrivez simplement le SQL vous-même. Cela vous fera gagner un peu de temps.
# All on one line:
Artist.find_by_sql
"SELECT `artists`.* FROM `artists`
WHERE `artists`.`id` = #{params[:artist_id].to_i} LIMIT 1"
ARel/MySQL expliquer ?
Rails peut aider à expliquer ce que MySQL essaie de faire :
Artist.find(params[:artist_id]).explain
http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/
Peut-être pouvez-vous découvrir une sorte de différence entre les requêtes qui réussissent et celles qui échouent, comme la façon dont le explain
utilise des index ou des optimisations.
la gemme mysql2 ?
Pouvez-vous essayer de passer de la gemme mysql à la gemme mysql2 ? Quel échec obtenez-vous lorsque vous passez à la gemme mysql2 ?
volatilité ?
Peut-être y a-t-il autre chose qui modifie le hachage des paramètres à la volée, donc vous le voyez lorsque vous l'imprimez, mais il a changé au moment où la requête s'exécute ?
Essayez d'affecter la variable dès que vous recevez les paramètres :
artist_id = params[:artist_id]
... whatever code here...
@artist = Artist.find(artist_id)
pas le hachage des paramètres ?
Vous avez écrit "Ce qui signifie que Rails ne passe pas dans le params[:artist_id] qui est évidemment dans le hachage params." Je ne pense pas que ce soit le problème - je suppose que vous voyez cela parce que Rails utilise le "?" comme espace réservé pour une déclaration préparée.
Pour le savoir, lancez les commandes suggérées par @Mori et comparez-les; ils devraient être identiques.
Article.find(42).to_sql
Article.find(params[:artist_id]).to_sql
déclarations préparées ?
Il peut s'agir d'un problème de cache d'instructions préparées, lorsque la requête est réellement exécutée.
Voici le code qui échoue - et il y a un gros avertissement.
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
Essayez de configurer votre base de données pour désactiver les instructions préparées, pour voir si cela fait une différence.
Dans votre ./config/database.yml
fichier :
production:
adapter: mysql
prepared_statements: false
...
des bogues avec des instructions préparées ?
Il peut y avoir un problème avec Rails ignorant ce paramètre. Si vous voulez en savoir plus à ce sujet, consultez cette discussion et correction de bogue par Jeremey Cole et Aaron :https://github.com/rails/rails/pull/7042
Heroku peut ignorer le paramètre. Voici un moyen d'essayer de remplacer Heroku en corrigeant la configuration de ready_statements :https://github.com /rails/rails/issues/5297
supprimer le cache des requêtes ?
Essayez de supprimer ActiveRecord QueryCache pour voir si cela fait une différence :
config.middleware.delete ActiveRecord::QueryCache
http://edgeguides.rubyonrails.org/configuring.html#configuring-middle
essayer postgres ?
Si vous pouvez essayer Postgres, cela pourrait aussi le clarifier. Ce n'est peut-être pas une solution à long terme pour vous, mais cela isolerait le problème de MySQL.