1

このアプリケーションは PostGIS に基づいており、RGeo の simple_mercator_factory を使用してデータを保存します。

ポリゴン レコードが作成され、ポイントとの関連付けは静的です (つまり、更新する必要はありません)。PostGIS 計算のオーバーヘッドを削減するには、ポリゴンに属するポイントを結合テーブルに入力し、(rTree の代わりに) bTree を使用してインデックス付き結合テーブルで検索を実行するのが理にかなっています。

問題は、結合レコードの効率的な作成です。現在のところ:

@line_string1 = RGeo::Geographic.simple_mercator_factory.line_string([@point_a, @point_b, @point_c, @point_d])
@points = Point.all
@points_in ||= []
@points.each do |point|
  this_point = point.lonlat
  @this_poly = RGeo::Geographic.simple_mercator_factory.polygon(@line_string1)
  if this_point.intersects?(@this_poly)
      @add_point = pointpolygon.new(:point_id => point.id, :polygon_id => @polygon.id)
      @add_point.save
  end
end

クエリ プランは許容範囲です

EXPLAIN for: SELECT "point".* FROM "points"
                         QUERY PLAN
-------------------------------------------------------------
 Seq Scan on points  (cost=0.00..210.10 rows=8110 width=99)
(1 row)

ただし、@add_point関数は 14 から 16 ミリ秒の間でクロッキングしています。83 レコードのセットでは、約 1.6 秒です。しかし、合計は一致しません
Completed 302 Found in 7796.9ms (ActiveRecord: 358.5ms)
: 結合レコードを書き込むことなく、同じクエリ プラン (および時間) を実行する別のメソッドを実行すると、
Completed 200 OK in 1317.5ms (Views: 49.8ms | ActiveRecord: 64.0ms)
2 つの疑問が生じます。もっと平凡なことに、開発モードの条件を除けば、なぜ合計がこれほど膨れ上がったのですか?

しかし、もっと重要なのは、結合テーブルレコードの書き込みを別のスレッド (after_update?) にラップオフする方法はありますか? (1000 レコードを書き込むことができると考えると...)

4

1 に答える 1

0

@Jakubが正しく指摘しているように、すべての有効なポイントを1回のショットで抽出する方法:

def valid_points
  Point.order("id").joins("INNER JOIN points ON points.id=#{id} AND st_contains(polygon.poly, points.lonlat)").all
end  

その後、コントローラーによって呼び出されます

  @valid_points = @polygon.valid_points
  @valid_points.each do |point|
    @add_point = Pointpolygon.new(:point_id => point.id, :polygon_id => @polygon.id)
    @add_point.save
  end

はるかに優れた応答時間が得られます。1000 マッチまでのテスト ケースの場合、開発モードでのレコード作成あたりの作成時間は 1.2 ~ 1.4 ミリ秒です。

于 2015-08-22T11:05:09.020 に答える