【发布时间】:2016-07-27 10:11:19
【问题描述】:
我正在使用 MariaDB 10.1.16,我有一个包含 170 万个英国邮政编码的表格,将用于位置自动完成、地理编码和反向地理编码。
下面是表结构:
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| postcode | varchar(8) | NO | PRI | NULL | |
| district | varchar(4) | YES | | NULL | |
| postal_town | varchar(35) | YES | | NULL | |
| county | varchar(37) | YES | | NULL | |
| country | varchar(16) | YES | | NULL | |
| easting | int(11) | YES | | NULL | |
| northing | int(11) | YES | | NULL | |
| latitude | decimal(7,5) | YES | | NULL | |
| longitude | decimal(7,5) | YES | | NULL | |
| type | varchar(14) | YES | | NULL | |
| id | varchar(32) | YES | | NULL | |
+-------------+--------------+------+-----+---------+-------+
在表中查询单个邮政编码会立即返回结果:
MariaDB [dev]> SELECT * FROM uk_postcodes WHERE postcode = "CH5 3NS";
+----------+----------+-------------+--------+---------+---------+----------+----------+-----------+------------+----------------------------------+
| postcode | district | postal_town | county | country | easting | northing | latitude | longitude | type | id |
+----------+----------+-------------+--------+---------+---------+----------+----------+-----------+------------+----------------------------------+
| CH5 3NS | CH5 | Hawarden | Clwyd | Wales | 331718 | 365725 | 53.18422 | -3.02325 | Geographic | f99a64139bfb8cf8091ca870808b355b |
+----------+----------+-------------+--------+---------+---------+----------+----------+-----------+------------+----------------------------------+
1 row in set (0.00 sec)
但是我现在想使用我当前的位置来查找最近的邮政编码。
我的大概位置是:53.1852582, -3.0198408999999997
我的查询:
MariaDB [dev]> SELECT postcode, ( 3959 * acos( cos( radians( 53.1852582 ) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-3.0198408999999997) ) + sin( radians(53.1852582) ) * sin( radians( latitude ) ) ) ) AS distance
-> FROM uk_postcodes
-> ORDER BY distance ASC
-> LIMIT 1;
+----------+---------------------+
| postcode | distance |
+----------+---------------------+
| CH5 3PF | 0.13510896180231324 |
+----------+---------------------+
1 row in set (3.10 sec)
虽然结果是正确的,但它花费的时间太长了。但为什么呢?
【问题讨论】:
-
由于您使用 ORDER BY,因此您必须在返回数据之前对所有条目执行计算并对结果集进行排序。这需要相当长的时间...如果您对查询进行 EXPLAIN 说明,您可能会明白为什么...
-
您将需要对数据使用某种空间索引,否则您将无法从数据库中获得任何合理的性能。
-
您真的需要查看所有条目,还是将数据减少到预定义的半径就足够了?
-
@Olli 现在是的,我可以将其限制在特定区域,从而将总可能性从 1.7M 减少到 23K。但本质上这并不能解决问题,所以我仍然真的需要理解为什么需要这么长时间。
标签: mysql google-maps