Gan*_*row 11 postgresql postgis postgresql-9.2 gist-index
如果我有一个关于返回附近咖啡馆的查询:
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
)
)
Run Code Online (Sandbox Code Playgroud)
如何选择距离以及按距离排序?
有没有比这更有效的方法:
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
Run Code Online (Sandbox Code Playgroud)
Erw*_*ter 12
首先,使用
ST_SetSRID(ST_MakePoint(c.longitude, c.latitude),4326)::geography
Run Code Online (Sandbox Code Playgroud)
代替
ST_GeographyFromText('SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')')Run Code Online (Sandbox Code Playgroud)
ST_MakePoint虽然不符合 OGC 标准,但通常比ST_GeomFromText和更快、更精确ST_PointFromText。如果您有原始坐标而不是 WKT,它也更容易使用。
接下来,要使查询更短并且只输入一次搜索参数(对性能没有太大影响),请使用子查询(或 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;Run Code Online (Sandbox Code Playgroud)
最后,您需要一个GiST 索引来加快大表的速度。
每个文档ST_DWithin():
此函数调用将自动包含一个边界框比较,它将利用几何上可用的任何索引。
您可以将其与答案开头的表达式的功能索引一起使用。但是我会存储一个geography类型列以开始(让我们命名它thegeog)并创建一个简单的 GiST 索引,如:
CREATE INDEX cafes_thegeog_gist ON cafes USING gist(thegeog);
Run Code Online (Sandbox Code Playgroud)
到达这个更简单和更快的查询:
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;
Run Code Online (Sandbox Code Playgroud)
更新以匹配geography与geography,如通过评论@ LR1234567指出。作为替代方案,您可以使用geometry. 这里使用的所有函数都适用于两者(除了ST_MakePoint,因此附加了强制转换)。有什么不同?
如果您想获得半径范围内的n 个最近的咖啡馆,请考虑“最近的邻居”搜索。往往更方便。
| 归档时间: |
|
| 查看次数: |
5921 次 |
| 最近记录: |