Ruby Geocoder附近很慢

使用Rails 3.2,Ruby 1.9,geocoder gem。 我的控制器中有以下查询:

# 1500+ms to load nearby_shops = (current_shop.nearbys(10, :order => 'overall_rating DESC') .where(:shop_type => shop_type).includes(:photos, :active_property_list => :hotel_image_lists).limit(5)) # SQL Shop Load (4045.6ms) SELECT shops.*, 3958.755864232 * 2 * ASIN(SQRT(POWER( SIN((36.111927 - shops.lat) * PI() / 180 / 2), 2) + COS(36.111927 * PI() / 180) * COS(shops.lat * PI() / 180) * POWER(SIN((-115.171229 - shops.lng) * PI() / 180 / 2), 2))) AS distance, CAST(DEGREES(ATAN2( RADIANS(shops.lng - -115.171229), RADIANS(shops.lat - 36.111927))) + 360 AS decimal) % 360 AS bearing FROM `shops` WHERE `shops`.`shop_type` = 'food' AND (shops.lat BETWEEN 35.96719521688915 AND 36.25665878311085 AND shops.lng BETWEEN -115.3503819353204 AND -114.9920760646796 AND 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((36.111927 - shops.lat) * PI() / 180 / 2), 2) + COS(36.111927 * PI() / 180) * COS(shops.lat * PI() / 180) * POWER(SIN(( -115.171229 - shops.lng) * PI() / 180 / 2), 2))) <= 10 AND shops.id != 85155) ORDER BY overall_rating DESC LIMIT 5 - shops.lat) * PI() / 180 / 2), 2) + COS(48.8582411618 * PI() / 180) * COS(shops.lat * PI() / 180) * POWER(SIN((2.2945044899 - shops.lng) * PI() / 180 / 2), 2))) <= 100 AND shops.id != 517) ORDER BY distance ASC LIMIT 25 OFFSET 0 

问题在于nearbyslongitudelatitude上进行计算。 我已经为longitudelatitude列添加了索引,但它没有改进任何东西。

我怎样才能改善这个?

P / S:我删除了无关的条件,这些条件对查询的速度没有贡献。

这可能不是最精确或最优雅的解决方案,但为什么不只是稍微捏造数学。 您可以编写一个执行如下操作的select子句:

  .select(["id, name, 69.0975851*sqrt(POWER(shops.lat-?,2) + COS(?*PI()/180)*POWER(shops.lon-?,2)) AS DISTANCE", loc.lat, loc.lat, loc.lon]) 

如果你只是处理小的(<500英里)距离,你真的不需要使用那个毛茸茸的大圆公式。 你最终会得到相同的〜几乎〜答案的一小部分计算成本。