sql - 将数组放入 WHERE IN 子句 Ruby on Rails
问题描述
我正在构建一个 ruby on rails 应用程序,它使用原始 SQL 来查询我的数据库,因为我听说它比使用 ActiveRecord 执行得更好。我有一个数组,用于存储 BigInts 的项目列表。例如:
my_items_id = [43627164222, 43667161211, 43667161000]
我的 sql 语句应该返回表中的所有值,其中 id 是my_items_id
.
sql = "select * from table1 where id IN #{my_items_id}"
records_array = ActiveRecord::Base.connection.execute(sql)
这不起作用的原因是因为 my_items_id 是一个数组,我知道这一点。但是将其转换为的最佳方法是:(43627164222, 43667161211, 43667161000)
以便 sql 语句真正起作用。
解决方案
你写你想避免 ActiveRecord 因为读取原始 SQL 执行得更好。这可能是正确的,尤其是当您必须处理数百万条记录时。
但是,与原始 SQL 相比,ActiveRecord 变慢的原因肯定不是预先构建和清理查询。ActiveRecord 比较慢,因为它解析结果并返回数据库模型的实例,而不是简单的类似哈希的结构。
也就是说,IMO 可以使用 ActiveRecord 查询语言构建查询,但在普通连接上将其作为原始 SQL 运行。然后,您仍然会受益于 ActiveRecord 的查询语言和它针对 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)
处理数百万条记录时的另一个问题不仅是 ActiveRecord 的解析部分,还有数百万条记录消耗大量 RAM 并因此可能比预期慢的事实。ActiveRecord 也有解决这个问题的辅助方法——比如find_each
orfind_in_batches
。这些方法不会同时将所有记录加载到内存中,而是以较小的批量加载,并且可以大大提高操作的整体性能。
Table1.where(id: my_items_id).find_each do |item|
# handle each item
end
或者您可能只需要原始记录的一部分,而不是所有列然后使用pluck
会有帮助。它再次提高了 ActiveRecord 查询的性能,因为它返回一个简单的嵌套数组而不是复杂的 ActiveRecord 实例——这节省了解析和内存的时间。
另一个问题是在肯定丢失的数据库索引中对数百万条记录进行缓慢查询。但是如果不了解更多关于数据库结构和慢查询的信息,就不可能给出任何建议。
推荐阅读
- jquery - 当用户使用内置注销 url 从 Django Web 应用程序注销时清除 Cookie 和会话数据
- html - 如何将标题背景图像保持在视口中的恒定水平点
- javascript - 拒绝从 '' 执行脚本,因为它的 MIME 类型
- azure - 将多个文件和文件夹传输到 Azure 存储
- java - JTable 最后一个值 null
- javascript - 返回值的最佳实践
- python - 使用 pyodbc UPDATE 命令更新 sql 表时如何解决 SQL 绑定错误?
- c# - TcpListener.AcceptTcpClientAsync 方法不监听客户端请求
- javascript - Azure Timeseries 见解 API 所有 API 请求的内部服务器错误
- php - 从mysql获取记录,不包括值