数据库:查询地理位置数据的最佳性能方式?

Han*_*nkW 39 mysql database performance database-design

我有一个MySQL数据库.我将家庭存储在数据库中,并且只对数据库执行1次查询,但我需要以超快的速度执行此查询,并且这将返回方形框内的所有家庭地理纬度和经度.

SELECT * FROM homes 
WHERE geolat BETWEEN ??? AND ???
AND geolng BETWEEN ??? AND ???
Run Code Online (Sandbox Code Playgroud)

如何存储我的地理数据的最佳方式,以便我可以执行此查询显示地理定位框中的所有家庭最快?

基本上:

  • 我是否使用最好的SQL语句来最快地执行此查询?
  • 是否存在任何其他方法,甚至可能不使用数据库,以便查询盒装地理位置范围内的房屋结果的最快方式?

如果有帮助,我在下面包含我的数据库表模式:

CREATE TABLE IF NOT EXISTS `homes` (
  `home_id` int(10) unsigned NOT NULL auto_increment,
  `address` varchar(128) collate utf8_unicode_ci NOT NULL,
  `city` varchar(64) collate utf8_unicode_ci NOT NULL,
  `state` varchar(2) collate utf8_unicode_ci NOT NULL,
  `zip` mediumint(8) unsigned NOT NULL,
  `price` mediumint(8) unsigned NOT NULL,
  `sqft` smallint(5) unsigned NOT NULL,
  `year_built` smallint(5) unsigned NOT NULL,
  `geolat` decimal(10,6) default NULL,
  `geolng` decimal(10,6) default NULL,
  PRIMARY KEY  (`home_id`),
  KEY `geolat` (`geolat`),
  KEY `geolng` (`geolng`),
) ENGINE=InnoDB  ;
Run Code Online (Sandbox Code Playgroud)

UPDATE

我理解空间会影响地球的曲率,但我最感兴趣的是返回最快的地理数据.除非这些空间数据库包以某种方式更快地返回数据,否则请不要推荐空间扩展.谢谢

更新2

请注意,下面没有人真正回答过这个问题.我真的很期待得到任何帮助.提前致谢.

Igo*_*aka 13

有在MySQL地理位置性能良好的纸在这里.

编辑很确定这是使用固定半径.此外,我并非100%确定计算距离的算法是最先进的(即它将通过地球"钻").

重要的是,该算法很便宜,可以对行数进行限定,以进行适当的距离搜索.


该算法通过将候选者放在源点周围的正方形中进行预过滤,然后计算以英里为单位的距离.

预先计算,或使用存储过程作为来源建议:

# Pseudo code
# user_lon and user_lat are the source longitude and latitude
# radius is the radius where you want to search
lon_distance = radius / abs(cos(radians(user_lat))*69);
min_lon = user_lon - lon_distance;
max_lon = user_lon + lon_distance;
min_lat = user_lat - (radius / 69);
max_lat = user_lat + (radius / 69);
Run Code Online (Sandbox Code Playgroud)
SELECT dest.*,
  3956 * 2 * ASIN(
    SQRT(
      POWER(
        SIN(
          (user_lat - dest.lat) * pi() / 180 / 2
        ), 2
      ) + COS(
        user_lat * pi() / 180
      ) * COS(
        dest.lat * pi() / 180
      ) * POWER(
        SIN(
          (user_lon - dest.lon) * pi() / 180 / 2
        ), 2
      )
    )
  ) as distance
FROM dest
WHERE 
  dest.lon between min_lon and max_lon AND
  dest.lat between min_lat and max_lat
HAVING distance < radius
ORDER BY distance
LIMIT 10
Run Code Online (Sandbox Code Playgroud)


Eve*_*ert 5

我遇到了同样的问题,并写了一个三部分的博客文章。这比地理索引要快。

简介基准测试SQL


tos*_*osh 2

如果您确实需要追求性能,您可以为数据定义边界框,并将预先计算的边界框映射到插入时的对象,并在稍后使用它们进行查询。

如果结果集相当小,您仍然可以在应用程序逻辑中进行精度校正(比数据库更容易水平扩展),同时能够提供准确的结果。

看一下 Bret Slatkin 的geobox.py,其中包含有关该方法的精彩文档。

如果您打算在可预见的将来执行更复杂的查询,我仍然建议您查看 PostgreSQL 和PostGIS ,而不是 MySQL。