Estoy creando una aplicación Ruby on Rails que usa SQL sin procesar para consultar mi base de datos porque escuché que funciona mejor que usar ActiveRecord. Tengo una matriz que almacena una lista de elementos que son BigInts. Por ejemplo:
my_items_id = [43627164222, 43667161211, 43667161000] Y se supone que mi instrucción sql devuelve todos los valores de una tabla donde el id es cualquiera de los que están en my_items_id .
sql = "select * from table1 where id IN #{my_items_id}" records_array = ActiveRecord::Base.connection.execute(sql) La razón por la que esto no funciona es porque my_items_id es una matriz y lo sé. Pero, ¿cuál es la mejor manera de convertirlo a: (43627164222, 43667161211, 43667161000) para que la instrucción sql realmente funcione?
Escribe que desea evitar ActiveRecord porque lee que SQL sin procesar funciona mejor. Probablemente eso sea correcto, especialmente cuando tiene que manejar millones de registros.
Pero lo que hace que ActiveRecord sea más lento en comparación con el SQL sin procesar ciertamente no es construir y desinfectar la consulta por adelantado. ActiveRecord es más lento porque analiza el resultado y devuelve instancias de los modelos de su base de datos en lugar de una estructura simple similar a un hash.
Dicho esto, en mi opinión, está perfectamente bien crear la consulta con el lenguaje de consulta ActiveRecord, pero ejecutarlo como SQL sin procesar en la conexión simple. Entonces aún se beneficiaría del lenguaje de consulta de ActiveRecord y sus características de seguridad contra las inyecciones de SQL.
my_items_id = [43627164222, 43667161211, 43667161000] sql = Table1.where(id: my_items_id).to_sql # <= Note the `to_sql` where records_array = ActiveRecord::Base.connection.execute(sql) Otro problema al manejar millones de registros no es solo la parte de análisis de ActiveRecord, sino el hecho de que millones de registros consumen mucha RAM y, por lo tanto, pueden ser más lentos de lo esperado. ActiveRecord también tiene métodos auxiliares para este problema, como find_each o find_in_batches . Estos métodos no cargan todos los registros en la memoria al mismo tiempo, sino en lotes más pequeños y pueden mejorar mucho el rendimiento general de la operación.
Table1.where(id: my_items_id).find_each do |item| # handle each item end O es posible que solo necesite partes de los registros originales y no todas las columnas, entonces usar pluck será útil. Mejora nuevamente el rendimiento de la consulta ActiveRecord porque devuelve una matriz anidada simple en lugar de instancias complejas de ActiveRecord, lo que ahorra tiempo en el análisis y la memoria.
Otro problema con consultas lentas en millones de registros en índices de bases de datos que ciertamente faltan. Pero sin saber más sobre la estructura de la base de datos y las consultas lentas, es imposible dar ningún consejo.