Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie erstellt Rails eine MySQL-Anweisung?

sql versuchen?

Wenn es nur diese eine Anweisung ist und Produktionsprobleme verursacht, können Sie den Abfragegenerator für den Moment weglassen? Mit anderen Worten, für sehr kurze Zeit schreiben Sie die SQL einfach selbst. Das verschafft Ihnen etwas Zeit.

# All on one line:
Artist.find_by_sql
  "SELECT `artists`.* FROM `artists` 
   WHERE `artists`.`id` = #{params[:artist_id].to_i} LIMIT 1"

ARel/MySQL erklären?

Rails kann dabei helfen zu erklären, was MySQL zu tun versucht:

Artist.find(params[:artist_id]).explain

http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/

Vielleicht können Sie einen Unterschied zwischen erfolgreichen und fehlgeschlagenen Abfragen entdecken, z. B. wie explain verwendet Indizes oder Optimierungen.

mysql2-Juwel?

Können Sie versuchen, vom mysql-Gem zum mysql2-Gem zu wechseln? Welchen Fehler erhalten Sie, wenn Sie zum mysql2-Gem wechseln?

Volatilität?

Vielleicht gibt es noch etwas anderes, das den Parameter-Hash im laufenden Betrieb ändert, sodass Sie es sehen, wenn Sie es drucken, aber es ist geändert, wenn die Abfrage ausgeführt wird?

Versuchen Sie, die Variable zuzuweisen, sobald Sie die Parameter erhalten:

artist_id = params[:artist_id]
... whatever code here...
@artist = Artist.find(artist_id)

nicht der Parameter-Hash?

Sie schrieben:„Meaning Rails is not passing in the params[:artist_id] was sich offensichtlich im params-Hash befindet.“ Ich glaube nicht, dass das das Problem ist - ich nehme an, dass Sie das sehen, weil Rails das "?" als Platzhalter für eine vorbereitete Anweisung.

Um dies herauszufinden, führen Sie die von @Mori vorgeschlagenen Befehle aus und vergleichen Sie sie. sie sollten gleich sein.

Article.find(42).to_sql
Article.find(params[:artist_id]).to_sql

vorbereitete Erklärungen?

Könnte ein Cache-Problem für vorbereitete Anweisungen sein, wenn die Abfrage tatsächlich ausgeführt wird.

Hier ist der Code, der fehlschlägt – und es gibt eine fette Warnung.

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

Versuchen Sie, Ihre Datenbank so zu konfigurieren, dass vorbereitete Anweisungen deaktiviert werden, um zu sehen, ob das einen Unterschied macht.

In Ihrer ./config/database.yml Datei:

production:
   adapter: mysql
   prepared_statements: false
   ...

Fehler bei vorbereiteten Anweisungen?

Es kann ein Problem mit Rails geben, das diese Einstellung ignoriert. Wenn Sie mehr darüber wissen möchten, sehen Sie sich diese Diskussion und Fehlerbehebung von Jeremey Cole und Aaron an:https://github.com/rails/rails/pull/7042

Heroku kann die Einstellung ignorieren. Hier ist eine Möglichkeit, wie Sie versuchen können, Heroku zu überschreiben, indem Sie das Setup für vorbereitete_Anweisungen patchen:https://github.com /rails/rails/issues/5297

den Abfrage-Cache entfernen?

Versuchen Sie, den ActiveRecord QueryCache zu entfernen, um zu sehen, ob das einen Unterschied macht:

config.middleware.delete ActiveRecord::QueryCache

http://edgeguides.rubyonrails.org/configuring.html#configuring-middle

postgres ausprobieren?

Wenn Sie Postgres ausprobieren können, könnte das auch Abhilfe schaffen. Das ist vielleicht keine langfristige Lösung für Sie, aber es würde das Problem auf MySQL eingrenzen.