ruby-on-rails - 比较 2 个大型 ActiveRecord 关系进行排序
问题描述
我有 2 个大ActiveRecord::Relations
的,每个都有 10 或 100 的数千条用户记录,我们称它们ar1
为ar2
. 我想进行排序ar1
,以便所有出现在 中的记录ar2
都放在ar1
.
这很容易做到sort_by
,但由于记录的数量如此之大,sort_by
在某些情况下执行需要一分钟以上。
我认为我最好的选择是尝试通过 ActiveRecord 以这种方式对记录进行排序,但我找不到任何方法来做到这一点。有没有办法使用 ActiveRecord 或其他方法快速完成此结果?
谢谢!
编辑:
这是我使用的排序代码:ar1.sort_by { |e| ar2.index(e) || Float::INFINITY }
解决方案
我会首先说你并不需要sort_by
!
您可以通过以下方式实现相同的目标:
ar1.sort_by { |e| ar2.index(e) || Float::INFINITY }
采用类似于以下的方法:
result = ((ar2 & ar1) + ar1).uniq
这要快得多。
这是支持此建议的简单基准。
require 'benchmark'
ar1 = 100_000.times.map {|x|( 100_000_000 * rand).to_i }.uniq
ar2 = 100_000.times.map {|x|( 100_000_000 * rand).to_i }.uniq
puts ar1.size
puts ar2.size
Benchmark.bm do |x|
result_2 = []
result_1 = []
x.report('sort') do
result_2 = ar1.sort_by { |e| ar2.index(e) || Float::INFINITY }
result_2.size
end
x.report('array') do
result_1 = ((ar2 & ar1) + ar1).uniq
result_1.size
end
puts result_1.size
puts result_2.size
puts result_1 == result_2
end
给出了一些不错的结果
user system total real
sort 45.287331 0.012233 45.299564 ( 45.539641)
array 0.010782 0.004000 0.014782 ( 0.014792)
我省略了一些验证输出。
现在是 ActiveRecord 部分。根据ar2
集合大小,您可以检索 id 并以此对第二个查询进行排序。鉴于ar1 = first_query.order(first_order)
ar2_ids = second_query.pluck(:id)
ar1 = first_query.order("FIELD(id, #{ar2_ids.join(',')}), first_order")
这将保留第ar2
一个和其他稍后。您将需要调查 id 的大小,ar2
因为根据您的数据库,提供具有数千个 id 的订单查询可能不是最理想的。
在考虑了这个问题之后,我会选择数组操作方法来保持简单。我不会选择数据库解决方案,因为它很可能会破坏查询的可读性,太多了。
这一切都取决于你的问题的细节!我希望这有帮助。
推荐阅读
- spring - 使 Custom Filter 和 WebSecurityConfig 在 Actuator 之后运行
- python-3.x - 大熊猫当前行上方/下方的总和列
- azure - 无法使用 Invoke-RestMethod 捕获“代理块页面”错误/尝试忽略 Catch
- rust - 为什么我不能使用 use crate::utils?
- visual-studio-code - 在终端上运行脚本的Vscode快捷方式?
- javascript - 使用firebase从react native发送OTP时面临问题
- json - jq - 仅从数组中选择和过滤某些对象
- sql - 使用最新数据更新表而不删除和复制
- jitterbit - 使用 Jitterbit 将 application/x-www-form-urlencoded Body 发布到 REST API
- java - 使用 Spring Boot Maven 的 PostgreSQL 的神秘数据库名称