sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo construye Rails una declaración MySQL?

probar sql?

Si es solo esta declaración y está causando problemas de producción, ¿puede omitir el generador de consultas solo por ahora? En otras palabras, a muy corto plazo, simplemente escriba el SQL usted mismo. Esto le dará un poco de tiempo.

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

¿Explicación de ARel/MySQL?

Rails puede ayudar a explicar lo que MySQL intenta hacer:

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

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

Quizás pueda descubrir algún tipo de diferencia entre las consultas que tienen éxito y las que fallan, como la forma en que explain usa índices u optimizaciones.

gema mysql2?

¿Puedes intentar cambiar de la gema mysql a la gema mysql2? ¿Qué falla obtienes cuando cambias a la gema mysql2?

volatilidad?

¿Quizás hay algo más que cambia el hash de parámetros sobre la marcha, para que lo vea cuando lo imprima, pero haya cambiado cuando se ejecuta la consulta?

Intente asignar la variable tan pronto como reciba los parámetros:

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

¿No es el hash de parámetros?

Usted escribió "Significa que Rails no pasa los parámetros [:artist_id], que obviamente está en el hash de parámetros". No creo que ese sea el problema. Espero que estés viendo esto porque Rails está usando el "?" como marcador de posición para una declaración preparada.

Para averiguarlo, ejecute los comandos sugeridos por @Mori y compárelos; deberían ser iguales.

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

declaraciones preparadas?

Podría ser un problema de caché de declaración preparada, cuando la consulta se ejecuta realmente.

Aquí está el código que está fallando, y hay una gran advertencia.

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

Intente configurar su base de datos para desactivar declaraciones preparadas, para ver si eso hace la diferencia.

En tu ./config/database.yml archivo:

production:
   adapter: mysql
   prepared_statements: false
   ...

¿errores con declaraciones preparadas?

Puede haber un problema con Rails al ignorar esta configuración. Si desea obtener más información al respecto, consulte esta discusión y corrección de errores de Jeremey Cole y Aaron:https://github.com/rails/rails/pull/7042

Heroku puede ignorar la configuración. Esta es una manera de intentar anular Heroku parcheando la configuración de las declaraciones preparadas:https://github.com /rieles/rieles/problemas/5297

¿eliminar la caché de consultas?

Intente eliminar ActiveRecord QueryCache para ver si eso hace la diferencia:

config.middleware.delete ActiveRecord::QueryCache

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

probar postgres?

Si puede probar Postgres, eso también podría aclararlo. Puede que no sea una solución a largo plazo para usted, pero aislaría el problema a MySQL.