Yelp如何有效地计算数据库中的距离?


9

例如,说我有一张桌子:

Business(BusinessID, Lattitude, Longitude)

所有这些都被索引了。也有一百万条记录

假设我想寻找最接近106.5的企业,该怎么办?

如果我做

SELECT *
FROM Business
WHERE (Some formula to compute distance here) < 2000

例如,或者如果我这样做

SELECT *
FROM Business
TOP 20

理论上,计算机将必须计算所有biz的距离,而实际上,只有那些纬度和经度在一定范围内的距离才应计算。

那么,如何在PhP或SQL中做我想做的事情?

到目前为止,我很感谢您的回答。我正在使用mysql,它们没有比明显的解决方案更有效的方法。MySQL空间也没有计算距离功能。

Answers:


8

如果我正确理解了该问题(并且不确定是否会这样做),则您担心"(Some formula to compute distance here)"每次执行查询时都要对表中的每一行进行计算吗?

这可以通过使用on的索引在一定程度上减轻latitudelongitude因此我们只需要计算包含实际所需圆的点的“盒”的距离即可:

select * from business
where (latitude>96 and latitude<116) and 
      (longitude>-5 and longitude<15) and 
      (Some formula to compute distance here) < 2000

选择96、116等以匹配值“ 2000”的单位与要计算距离的地球上的点。

它使用索引的精确程度将取决于您的RDBMS及其计划者所做的选择。

一般而言,这是优化一种最邻近搜索的原始方法。如果您的RDBMS支持GiST索引(如postgres),则应考虑改用它们。


我用的是mysql。但是,某些mysql引擎虽然不支持innodb,但支持geopatial。
user4951 2012年

我对吗,您没有选择从MySQL进行更改的权利吗?在这种情况下,请标记问题的mysql
杰克说试topanswers.xyz

实际上,现在我现在添加myisam的辅助表,然后该如何有效地做到这一点?
user4951 2012年

好吧,我可以使用mongodb。我还没有决定。但是,我对mysql最熟悉。
user4951 2012年

1
我的建议是尽可能地熟悉postgres-与MongoDB相比,它与MySQL非常相似,并且具有可靠的空间数据历史,在其他地方的注释表明您更喜欢“免费”。
杰克说请尝试topanswers.xyz 2012年

6

(公开:我是Microsoft SQL Server专家,所以我的回答受此影响。)

要真正有效地做到这一点,您需要两件事:缓存和本机空间数据支持。 空间数据支持使您可以直接在数据库中存储地理和几何数据,而无需即时进行密集/昂贵的计算,还可以建立索引以非常快速地找到与当前位置(或最有效的路线等)最接近的点。

如果要扩展,缓存,缓存很重要。最快的查询是您从未做出过的查询。每当用户要求最接近他的东西时,您就将其位置和结果集存储在Redis或memcached之类的缓存中达几个小时。公司位置不会在4个小时内发生变化-好吧,如果有人编辑公司,它们可能会发生变化,但是您不一定需要立即在所有结果集中进行更新。


我无法从您的链接算出SQL Server是否确实以对获取附近点列表有用的方式对空间数据进行索引-是吗?
杰克说尝试topanswers.xyz 2011年


问题是我正在使用mysql,并且我已经证实它们没有比Jack Douglas所规定的算法更有效的算法。我不知道mysql是否会做类似缓存之类的事情。Microsoft SQL是付费的,而mysql是免费的
user4951 2011年

1
公司位置不会一直改变,但是人们的位置会改变。
user4951 2012年

0

Yelp可能使用GIS

PostgreSQL具有PostGIS的 GIS参考实现。Yelp可能使用的MySQL在任何方面都逊色。对于类似Yelp的情况,几乎可以肯定的是,

  • 用户
  • 潜在的目的地

这些坐标几乎可以肯定在WGS84中,并以地理类型存储。在PostgreSQL和PostGIS中,看起来像这样,

CREATE TABLE businesses (
  id   int               GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  name text,
  geog geography(point)
);
CREATE INDEX ON businesses USING gist(geog);
.... fill table
ANALYZE businesses;

他们会填那个表。然后他们从您的手机中获取WGS84坐标并生成一个查询,例如使用SQL Alchemy(对于Yelp),

SELECT *
FROM businesses AS b
WHERE ST_DWithin( b.geog, ST_MakePoint(userLong,userLat) );

有关更多信息,请参见我们的,并查看@StackExchange地理信息系统

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.