【问题标题】:Is there an efficient means of using ActiveRecord#Pluck for my situation?是否有针对我的情况使用 ActiveRecord#Pluck 的有效方法?
【发布时间】:2018-07-19 17:27:00
【问题描述】:

我需要向一个新数据库中插入大量数据。就像 lot 的数据一样,在这个查询的上下文中,甚至纳秒也算在内。我正在使用 activerecord-import 批量插入 Postgres,但这对于这个问题的范围并不重要。这是我需要的:

对于现有数据库中的每条记录,我需要一个如下所示的数组:

[uuid, timestamp, value, unit, different_timestamp]

问题是 uuid 存储在我循环访问该对象的父对象上,因此 #pluck 对除此之外的每个组件都有效。更烦人的是它存储为实际的 uuid,而不是字符串,并且还需要在新数据库中存储为 uuid(不是字符串)。我不确定,但我认为#pluck 内使用SELECT 会返回一个字符串。

但也许更大的问题是我需要在再次插入之前对value 的值进行转换。这是一个简单的转换,实际上只是 value / 28 或其他东西,但我发现很难将其转换为 #pluck 而不附加 #each_with_object 或其他东西(这会大大减慢速度)

这是现在的查询。根据上面概述的阻塞加载整个记录对我来说似乎真的很愚蠢。我希望有一个替代方案。

Klass.find_each do |klass|
    Data.where(token: klass.token).find_each do |data|
      data << [
        klass.uuid,
        data.added_at,
        data.value / conversion,
        data.unit, 
        data.created_at
      ]
    end
end

不,父级和Data 现在没有关联,这不是一个选项,所以我不能急切加载或只是调用Klass.data(在此转换后它们将被链接)。

所以理想情况下,这就是我正在寻找的:

Data.where(token: klass.token).pluck(:added_at, :value, :unit, :created_at)

但使用上述参数。

【问题讨论】:

  • 你不能完全绕过AR,直接说insert into target_table (...) select ...吗?您可以在select 中包含文字、计算、连接等。如果您正在导入数据,那么可能会导入到临时表中,然后在数据库中进行合并。如果您正在处理大量数据并试图加快处理速度,那么 ORM 是您最不想涉及的事情,您希望将逻辑推送到数据库中。
  • @muistooshort 遗憾的是,我必须在这个 rake 任务的某个级别上使用 activerecord,因为我们正在从各种对象中提取信息,一些相关的和一些不相关的,这些对象必须保持这些关联(或形成新的关联) ),我需要做的转换是可变的,并且取决于数据类型。不过公平地说,这里的瓶颈不是 INSERT 语句,它由 activerecord-import gem 以相当有效的方式处理。瓶颈在于我们需要将对象加载到内存中,而不仅仅是我们关心的列。

标签: ruby-on-rails ruby postgresql activerecord activerecord-import


【解决方案1】:

我想知道您是否可以将 SQL JOINpluck 结合起来:

Klass
  .joins('INNER JOIN datas ON datas.token = klasses.token')
  .pluck('klasses.uuid', 'datas.added_at', "datas.value / #{conversion.to_f}", 'datas.unit', 'datas.created_at')

【讨论】:

  • 感谢您的回复!可悲的是,这对我不起作用,因为转换取决于每个数据点的单位,可能不同,因此我们需要即时确定 conversion 的值。使用join 的另一个大问题是我正在处理数十亿行数据,并且一次将这么多的东西加载到内存中是不行的。
  • 但是 JOIN 不会将数十亿行数据加载到内存中;数据库实际上非常擅长管理大量数据,这就是他们所做的。就“动态确定conversion 的值”而言,您可能可以在SQL 中表达该逻辑。
  • 好的,在弄清楚如何处理转换之后,这似乎是最好的方法。我会将其标记为已解决。感谢您的帮助。
猜你喜欢
  • 2017-05-24
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多