近くのカフェを返すクエリがある場合:
SELECT * FROM cafes c WHERE (
ST_DWithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)'),
2000
)
)
距離を選択して距離で並べ替えるにはどうすればよいですか?
これよりも効率的な方法はありますか:
SELECT id,
ST_Distance(ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)'),
ST_GeographyFromText(
'SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')')
) as distance
FROM cafes c
WHERE (
ST_DWithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)'),
2000
)
) order by distance
最初、使用
_ST_SetSRID(ST_MakePoint(c.longitude, c.latitude),4326)::geography
_
の代わりに
ST_GeographyFromText('SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')')
OGCに準拠していない_
ST_MakePoint
_は、一般に_ST_GeomFromText
_および_ST_PointFromText
_よりも高速で正確です。また、WKTではなく未加工の座標がある場合にも使用する方が簡単です。
次へ、クエリを短くし、検索パラメータを1回だけ入力する(パフォーマンスに大きな影響を与えない)には、を使用しますサブクエリ(またはCTE):
_SELECT id
, ST_Distance(t.x
, ST_SetSRID(ST_MakePoint(c.longitude, c.latitude),4326)::geography) AS dist
FROM cafes c
, (SELECT ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)')) AS t(x)
WHERE ST_DWithin(t.x
, ST_SetSRID(ST_MakePoint(c.longitude, c.latitude),4326)::geography, 2000)
ORDER BY dist;
_
最後に、大きなテーブルでこれを高速にするには、Gistインデックスが必要です。 ST_DWithin()
のドキュメントごと :
この関数呼び出しには、ジオメトリで使用可能なインデックスを利用する境界ボックスの比較が自動的に含まれます。
答えの最初の式で function index を使用してこれを機能させることができます。しかし、最初にgeography
タイプの列を格納し(名前をthegeog
としましょう)、次のようなプレーンなGistインデックスを作成します。
_CREATE INDEX cafes_thegeog_Gist ON cafes USING Gist(thegeog);
_
このはるかに単純で高速なクエリに到達します。
_SELECT id, ST_Distance(t.x, thegeog) AS distance
FROM cafes c
, (SELECT ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)')) AS t(x)
WHERE ST_DWithin(t.x, thegeog, 2000)
ORDER BY distance;
_
コメントで@ LR1234567によって指摘されているように、geography
をgeography
と一致するように更新しました。別の方法として、geometry
を使用できます。ここで使用されるすべての関数は両方で機能します(_ST_MakePoint
_を除き、追加されたキャストを除く)。 違いは何ですか?
n最も近いカフェをすべて半径内で取得したい場合は、 "nearest neighbour" search 。多くの場合より便利です。