質問
postgisでは、 ST_GeomFromText
電話はとても高いですか?私がこの質問をする主な理由は、いくつかの条件に一致する別の点に最も近く、その他の点から一定の距離内にある点を検索しようとする、頻繁に呼び出されるクエリがあるためです。現在私がそれを書いた方法では、同じ ST_GeomFromText
2回:
$findNearIDMatchStmt = $postconn->prepare(
"SELECT internalid " .
"FROM waypoint " .
"WHERE id = ? AND " .
" category = ? AND ".
" (b.category in (1, 3) OR type like ?) AND ".
" ST_DWithin(point, ST_GeomFromText(?," . SRID .
" ),". SMALL_EPSILON . ") " .
" ORDER BY ST_Distance(point, ST_GeomFromText(?,", SRID .
" )) " .
" LIMIT 1");
これを書き直すより良い方法はありますか?
ややOT:プレビュー画面では、すべてのアンダースコアが次のようにレンダリングされます。 & # 9 5 ;
- それが投稿にそのように現れないことを願っています。
解決
私は信じません ST_GeomFromText()
過去に最適化しましたが、特に高価です PostGIS
関数を作成し、変数を宣言して、その結果を代入することでクエリを実行します。 ST_GeomFromText
変数に。
クエリのどの部分に時間がかかっているかを明確に把握できるため、さまざまなパラメーターを使用してクエリの実行プランを確認してみましたか?
実行時間のほとんどは、への呼び出しに費やされると思います。 ST_DWithin()
そして ST_Distance()
, ただし、id 列と category 列にインデックスが付けられていない場合は、興味深いテーブル スキャンが行われている可能性があります。
他のヒント
@ubiguchそれはそうです ST_DWithin
空間インデックスを使用するため、クエリするポイントの数がかなり早く削減されるようです。
navaid=> explain select internalid from waypoint where id != 'KROC' AND ST_DWithin(point, ST_GeomFromText('POINT(-77.6723888888889 43.1188611111111)',4326), 0.05) order by st_distance(point, st_geomfromtext('POINT(-77.6723888888889 43.1188611111111)',4326)) limit 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=8.37..8.38 rows=1 width=104)
-> Sort (cost=8.37..8.38 rows=1 width=104)
Sort Key: (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry))
-> Index Scan using waypoint_point_idx on waypoint (cost=0.00..8.36 rows=1 width=104)
Index Cond: (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry)
Filter: (((id)::text <> 'KROC'::text) AND (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry) AND ('0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry && st_expand(point, 0.05::double precision)) AND (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry) < 0.05::double precision))
(6 rows)
なしで order by
そしてその limit
, 、典型的なクエリは最大 5 ~ 10 個のウェイポイントしか返さないように見えます。したがって、返されるポイントに適用されるフィルターの追加コストについてはおそらく心配する必要はありません。