我一直在寻找在 Rails 中更快地获得此查询的最佳方法。由于 Geocoder 计算,目前需要花费大量时间。
Vehicle.includes(:user)
.where.not('users.id' => nil)
.where(country: 'United Kingdom')
.where.not(name: [nil, ''])
.select { |vehicle|
vehicle.longitude.present? &&
Geocoder::Calculations.distance_between(
[vehicle.latitude,vehicle.longitude],
[location.latitude,location.longitude]
).between?(0, 200)
}
注意:目前使用的数据库是PostgreSQL 9.5.14。
最佳答案
将
vehicle.longitude.present?
移动到数据库级别:.where.not(longitude: [nil, ''])
您的距离计算必须转移到数据库级别。在 Ruby 中加载所有记录并计算每条记录的距离会太慢。最简单的解决方案是添加 PostGIS:
- 添加PostGIS扩展到您的数据库。
- (可选)添加 adapter这将使处理数据变得更加容易。
- 将您现有的纬度/经度迁移到
st_point
。 - 将您的选择更改为将利用 ST_Distance 的范围功能。
作为 2) 的替代方案,您可以考虑将距离查询转移到 ElasticSearch 等搜索引擎。如果您正在创建的复杂查询遇到任何性能问题,我只会考虑。
关于ruby-on-rails - 如何使 select 查询在 rails 中相对更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53254668/