在MySQL中查找最近的邮政编码到Latitude Longitude

时间:2012-10-17 12:52:01

标签: mysql latitude-longitude spatial postal-code

我有一张表邮政编码,其中包含所有英国邮政编码(我认为约为1.8米)

CREATE TABLE `Postcode` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Postcode` varchar(8) DEFAULT NULL,
  `Postcode_Simple` varchar(8) DEFAULT NULL,
  `Positional_Quality_Indicator` int(11) DEFAULT NULL,
  `Eastings` int(11) DEFAULT NULL,
  `Northings` int(11) DEFAULT NULL,
  `Latitude` double DEFAULT NULL,
  `Longitude` double DEFAULT NULL,
  `LatLong` point DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `Postcode` (`Postcode`),
  KEY `Postcode_Simple` (`Postcode_Simple`),
  KEY `LatLong` (`LatLong`(25))
) ENGINE=InnoDB AUTO_INCREMENT=1755933 DEFAULT CHARSET=latin1;

我想要实现的是......给定一个坐标,找到最接近坐标的邮政编码。问题是我在查询时遇到了一些问题(实际上是在存储过程中)我写的是为了做到这一点。查询是:

SELECT
    Postcode
FROM
    (SELECT
        Postcode,
        GLENGTH(
            LINESTRINGFROMWKB(
                LINESTRING(
                    LatLong, 
                    GEOMFROMTEXT(CONCAT('POINT(', varLatitude, ' ', varLongitude, ')'))
                )
            )
        ) AS distance
    FROM
        Postcode
    WHERE
        NOT LatLong IS NULL) P
ORDER BY
    Distance
LIMIT
    1;

我遇到的问题是查询需要12秒才能运行,我不能花那么长时间才能得到结果。任何人都可以想到我可以可靠地加快这个查询的速度吗?

(这是查询的解释)

id select_type table      type possible_keys key    key_len ref    rows    Extra
1  PRIMARY     <derived2> ALL  (NULL)        (NULL) (NULL)  (NULL) 1688034 Using filesort
2  DERIVED     Postcode   ALL  LatLong       (NULL) (NULL)  (NULL) 1717998 Using where

我一直试图想出一种方法来缩小我必须执行距离计算的初始数据量,但是我还没有能够提出任何不限于查找邮政编码的内容在给定的距离内。

2 个答案:

答案 0 :(得分:1)

也许尝试一下以下几点:

SELECT Postcode, lat, lon
FROM
(
SELECT Postcode, MAX(latitude) AS lat, MAX(longitude) AS lon
FROM PostCode

-- field name
GROUP BY Postcode 

HAVING MAX(latitude)<varLatitude AND MAX(longitude)<varLongitude

LIMIT 1
) AS temp

这基本上会带来一个邮政编码,其lat和lon小于你指定的邮编,但大于任何小于你的vars的其他lat / lon组合;所以最有效的纬度/离子对你的vars,因此最接近的邮政编码。您可以尝试使用MIN和更高版本,然后反过来反过来。

以上只会得到一个结果/邮政编码。如果你想要找到一些更为简单的东西,比如在特定的纬度/长度范围内找到一组邮政编码,那么你应该看看https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql

中解释的公式。

答案 1 :(得分:0)

我写了tutorial几乎就是你所追求的。

基本上,你是在正确的路线上。为了提高搜索效率,您需要通过在LatLong字段上使用空间索引来减少GLength()计算的数量。如果您将搜索范围限制在精确区域,例如您将比较邮政编码的点周围10英里的多边形,您会发现查询更快。