prøve sql?
Hvis det kun er dette ene udsagn, og det forårsager produktionsproblemer, kan du så udelade forespørgselsgeneratoren lige nu? Med andre ord, på meget kort sigt skal du bare skrive SQL'en selv. Dette vil give dig lidt tid.
# All on one line:
Artist.find_by_sql
"SELECT `artists`.* FROM `artists`
WHERE `artists`.`id` = #{params[:artist_id].to_i} LIMIT 1"
ARel/MySQL forklare?
Rails kan hjælpe med at forklare, hvad MySQL forsøger at gøre:
Artist.find(params[:artist_id]).explain
http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/
Måske kan du opdage en eller anden form for forskel mellem de forespørgsler, der lykkes i forhold til mislykkede, såsom hvordan explain
bruger indekser eller optimeringer.
mysql2 perle?
Kan du prøve at skifte fra mysql-perlen til mysql2-perlen? Hvilken fejl får du, når du skifter til mysql2-perlen?
volatilitet?
Måske er der noget andet, der ændrer params-hashen i farten, så du kan se det, når du udskriver det, men det er ændret, når forespørgslen kører?
Prøv at tildele variablen, så snart du modtager parametrene:
artist_id = params[:artist_id]
... whatever code here...
@artist = Artist.find(artist_id)
ikke params hash?
Du skrev "Det betyder, at Rails ikke passerer i params[:artist_id] som åbenbart er i params hash." Jeg tror ikke, det er problemet - jeg forventer, at du ser dette, fordi Rails bruger "?" som pladsholder for en udarbejdet erklæring.
For at finde ud af det, kør kommandoerne foreslået af @Mori og sammenlign dem; de skal være de samme.
Article.find(42).to_sql
Article.find(params[:artist_id]).to_sql
forberedte erklæringer?
Kunne være et forberedt sætningscacheproblem, når forespørgslen rent faktisk udføres.
Her er koden, der fejler - og der er en stor fed advarsel.
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
Prøv at konfigurere din database til at slå forberedte sætninger fra for at se, om det gør en forskel.
I din ./config/database.yml
fil:
production:
adapter: mysql
prepared_statements: false
...
fejl med forberedte udsagn?
Der kan være et problem med, at Rails ignorerer denne indstilling. Hvis du vil vide meget mere om det, så se denne diskussion og fejlrettelse af Jeremey Cole og Aaron:https://github.com/rails/rails/pull/7042
Heroku ignorerer muligvis indstillingen. Her er en måde, hvorpå du kan prøve at tilsidesætte Heroku ved at rette opsætningen af preparerte_statements:https://github.com /rails/rails/issues/5297
fjerne forespørgselscachen?
Prøv at fjerne ActiveRecord QueryCache for at se, om det gør en forskel:
config.middleware.delete ActiveRecord::QueryCache
http://edgeguides.rubyonrails.org/configuring.html#configuring-middle
prøve postgres?
Hvis du kan prøve Postgres, kan det også rydde op. Det er måske ikke en langsigtet løsning for dig, men det ville isolere problemet til MySQL.