[英]Find nearest point using PostGIS
在带有 PostGIS 扩展的 PostgreSQL 12 上,我有两个表定义如下:
CREATE TABLE table_a (
id_a integer,
id_b integer,
coord geometry,
);
CREATE INDEX table_a_coord_idx ON table_a USING gist (coord);
CREATE TABLE table_b (
id_b integer,
coord geometry,
);
CREATE INDEX table_b_coord_idx ON table_b USING gist (coord);
这两个表都有大约 300 万个条目。 coord
列仅包含点几何。 id_b
的值最初是 null。
我的目标是为 table_a 中的每个点找到距table_a
最近的点并填写table_b
id_b
。 我编写了一个小的 Python 脚本来通过基于索引的 KNN 搜索来实现这一点:
import psycopg2 as pg
conn = pg.connect()
cur = conn.cursor()
cnt = 0
cur.execute('SELECT id_a, coord FROM table_a WHERE id_b IS NULL')
for row in cur.fetchall():
cnt += 1
cur.execute('SELECT id_b FROM table_b ORDER BY geom <-> %s LIMIT 1;', (row[1],))
nearest_vertex = cur.fetchone()
cur.execute('UPDATE table_a SET id_b=%s WHERE id_a=%s', (nearest_vertex[0], row[0]))
if cnt % 1000 == 0:
conn.commit()
conn.commit()
此代码有效。 但平均需要 0.6 秒才能完成一个条目,因此完成所有条目需要大约三周的时间。
有谁知道如何加快这个过程?
在循环中逐个处理记录会导致大量网络流量流向数据库。
相反,尝试在单个语句中一次更新所有条目(如果您愿意,可以从 pyton 脚本发送)。
UPDATE table_a
SET id_b = (
SELECT id_b
FROM table_b
ORDER BY table_b.geom <-> table_a.geom
LIMIT 1
)
WHERE id_b IS NULL;
有点晚了,但我的第一枪是检查这样的查询:
-- Find the nearest hospital to each school
-- that is within 3000 units of the school.
SELECT DISTINCT ON (s.gid) s.gid, s.school_name, s.geom, h.hospital_name
FROM schools s
LEFT JOIN hospitals h ON ST_DWithin(s.the_geom, h.geom, 3000)
ORDER BY s.gid, ST_Distance(s.geom, h.geom);
它来自 postgis 手册http://postgis.net/docs/manual-3.0/ST_DWithin.html 。 只要确保您在几何列上有索引并避免大半径。 半径越大,查询越慢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.