当前位置: 首页 > 知识库问答 >
问题:

在 PgSql 中,在庞大的数据集中找到最近邻的最佳查询是什么?

洪哲彦
2023-03-14

我有一个巨大的表(大约4000万行),称为nearest_spot,表示行(以linestring格式)和它们所到的最近点(大约有1500个不同的点,存储在另一个表中)。最近的_点表如下所示:

 data_id || spot_id || spot_name || link_geom 

其中data_id为主键,spot_id是spot表主键的外键,spot_name是spot名称(我知道冗余不好但我不允许修改数据库)和link_geom是行坐标。

数据库位于PostgreSQL 10.6、PostGIS 2.5中,链接geom列有一个基本索引,最近的点表已经进行了真空分析。

我的目标是尽可能快地找到数据记录中某个点的最近邻居(在此表中)。

我已经知道如何找到最近的邻居,我的问题是找到它需要的时间。我对PostgreSQL和PostGIS非常陌生,我一直在阅读他们的文档,阅读了很多关于KNN优化的主题,我一直在寻找最有效的答案,但我无法在5分钟内得到结果(有时会达到30分钟),即使只搜索一行。我尝试过的不同查询如下:

SELECT *
FROM( SELECT A.position, B.spot_id
      FROM data A, nearest_spot B
      WHERE A.id = 1
      AND ST_DWithin(A.position,B.link_geom,20)
      ORDER BY A.position <-> B.link_geom
      LIMIT 10;)
ORDER BY ST_Distance(A.position,B.link_geom)
LIMIT 1;

SELECT *
FROM( SELECT A.position, B.spot_id
      FROM data A, nearest_spot B
      WHERE A.id = 1
      AND ST_Buffer(A.position,20) && B.link_geom
      ORDER BY A.position <-> B.link_geom
      LIMIT 10;)
ORDER BY ST_Distance(A.position,B.link_geom)
LIMIT 1;

SELECT *
FROM( SELECT A.position, B.spot_id
      FROM data A, nearest_spot B
      WHERE A.id = 1
      AND ST_Intersects(ST_Buffer(A.position,20), B.link_geom)
      ORDER BY A.position <-> B.link_geom
      LIMIT 10;)
ORDER BY ST_Distance(A.position,B.link_geom)
LIMIT 1;

我用

我还使用了有关空间索引的文档,以及有关 的文档

编辑:我意识到我所有的坐标都存储为几何(SRID 4326),所以ST_DWithin调用,虽然有很好的语法,返回的不是20米内的所有行,而是20度内的所有行(地球),所以事实上我的ST_DWithin没有让结果集变得更小,这可能是它花了这么长时间的最大原因之一,ST_Buffer也是如此。我将尝试将所有坐标转换为地理(与::地理),然后将它们与米一起使用,希望我能看到改进


共有1个答案

斜和硕
2023-03-14

是否需要由数据库执行?我认为最快的方法可能是将1500个点加载到空间索引中,例如KD树、四叉树或R树。然后在40M点上迭代,并在索引中搜索最近的邻居。

不费吹灰之力,您应该能够每秒执行 100,000 到 500,000 次 NN 搜索,因此 40M NN 搜索大约需要 2 到 5 分钟。

 类似资料:
  • 我正在尝试使用jgraph T解决一个链接预测问题。我正在根据两个节点的邻居计算两个节点之间的相似性。每个节点都有一些属性。计算变得太多了,因为一些节点有大约700个邻居,而我有4500个这样的节点。我有谁对的700K边,我计算相似性。 现在,我不想使用节点的所有邻居,我只想使用每个节点的k个最近邻居来计算一对节点之间的相似度。我可以根据边共享的两个节点的属性数,或节点之间长度为n的最短路径数等,

  • 很抱歉打扰你,但我无法找到一个有效的解决我的问题的方法。我想做一个MongoDB查询,让我得到与SQL查询相同的结果:

  • 我有我的发电机数据库表如下: HashKey(日期)、RangeKey(时间戳) DB存储每天的数据(哈希键)和时间戳(范围键)。 现在我想查询过去7天的数据。我可以在一次查询中做到这一点吗?还是我需要每天调用dbb 7次?数据的顺序并不重要因此,有人可以建议一个有效的查询来做到这一点。

  • 问题内容: 我正在寻找一种借助Elasticsearch查找最近价格/数量的可能性。问题是我没有范围。我要实现的是,结果按最近距离排序。根据示例搜索查询,我的索引包含3个具有以下价格(数字)的文档:45、27、32 给定数字与我的搜索值29的“距离”为45-29 = 16 | 27-29 = -2 | 32-29 = 3,所以我希望搜索结果是按“距离”评分的,该数字距离给定价格不远。 搜索查询示例

  • 问题内容: 我有这种表,找到最大的标记 学生 外面应该是这样的 但我得到这种输出 我用SQL写这个 我该如何纠正sql? 问题答案: 在SQL Server中,您可以使用 尽管您也可以使用逻辑上等效的标准SQL

  • 问题内容: 是否有numpy-thonic方法(例如函数)在数组中查找最接近的值? 例: 问题答案: