【发布时间】:2018-02-26 08:39:10
【问题描述】:
我有一个查询,它获取给定位置周围的站点列表,并从另一个表中搜索与查询的站点具有相同坐标的行的 ID,并连接所有具有相同坐标的“行”列ID 作为从第二个表中查询的 ID。
查询如下所示
SELECT Instance,
Namespace,
Stations.Name,
Stations.Lat,
Stations.Lon,
Temp,
Humid,
(SELECT ID FROM transportData.stations WHERE stations.Lat = Stations.Lat AND stations.Lon = Stations.Lon) AS 'StationID',
( 6371 * acos( cos( radians(44.436292) ) * cos( radians( Stations.Lat ) ) * cos( radians( Stations.Lon ) - radians(26.102452) ) + sin( radians(44.436292) ) * sin(radians(Stations.Lat)) ) ) AS distance,
(SELECT GROUP_CONCAT(Line SEPARATOR ';') FROM transportData.timeTables WHERE timeTables.Station = StationID GROUP BY timeTables.Station) AS 'Lines'
FROM `Stations`
WHERE `Namespace` LIKE "%8"
HAVING distance < 0.1
ORDER BY distance
但是,这个查询只返回一个站点(在提供的坐标的 100 m 半径内)执行需要 58 秒。
关于如何优化它的任何建议?
编辑: 车站表:
+-----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| Instance | varchar(6) | NO | PRI | NULL | |
| Namespace | varchar(10) | NO | | NULL | |
| Name | varchar(255) | NO | | NULL | |
| Lat | decimal(9,6) | NO | | NULL | |
| Lon | decimal(9,6) | NO | | NULL | |
| Temp | float | YES | | NULL | |
| Humid | float | YES | | NULL | |
| Bio | varchar(3000) | YES | | NULL | |
| Photo | varchar(1000) | YES | | NULL | |
| Phone | varchar(255) | YES | | NULL | |
| Website | varchar(255) | YES | | NULL | |
| OpenHours | varchar(1024) | YES | | NULL | |
+-----------+---------------+------+-----+---------+-------+
transportData.stations 表:
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| ID | int(11) | NO | PRI | NULL | |
| Name | varchar(50) | NO | | NULL | |
| Lat | varchar(15) | NO | | NULL | |
| Lon | varchar(15) | NO | | NULL | |
| Type | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
时间表:
+----------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Line | varchar(10) | NO | | NULL | |
| Station | int(11) | NO | | NULL | |
| Weekdays | varchar(3500) | NO | | NULL | |
| Weekends | varchar(3500) | NO | | NULL | |
+----------+---------------+------+-----+---------+----------------+
编辑:我尝试使用一些 MariaDB 空间函数,发现它可以工作 ST_Distance(point(44.436292,26.102452), point(Lat, Lon)),但它给了我奇怪的读数,与来自我以前有的公式。这可能是因为ST_Distance返回的是平面上的距离,没用,因为它没有考虑地球的曲率。
【问题讨论】:
-
请显示您的表结构和索引结构。
-
该查询正在执行大量计算,并且当您在计算列上进行操作时,它需要进行表扫描。这些必然比索引版本慢。如果您正在做大量的 GIS 工作,请使用MySQL Spatial Extensions。
-
您能否以某种方式根据值过滤电台...如果距离为 0.1 公里...那么您要查找的电台的经度和纬度应该接近您的输入...应该会显着限制您的计算
-
@Martin 我已经添加了表结构。
-
好的,如果您使用 GPS 数据,有两个选择:1)您有一个小数据集并且知道大部分输出,因此您可以弥补一些东西;或者 2) 你真的使用空间数据,你使用空间列和空间索引(如果你需要和你的老板争论的话,我们谈论将 50s 更改为
标签: mysql sql database optimization