Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用纬度/经度索引mysql表以进行地理查找_Mysql_Database_Geospatial_Latitude Longitude_Indexing - Fatal编程技术网

使用纬度/经度索引mysql表以进行地理查找

使用纬度/经度索引mysql表以进行地理查找,mysql,database,geospatial,latitude-longitude,indexing,Mysql,Database,Geospatial,Latitude Longitude,Indexing,我有一个遗留innodb表,其中包含一个具有纬度/经度的业务。给定一个输入纬度/经度(低于51.2167/4.41667),查询将按距离(公里)的顺序返回第一个激活、启用、未删除的30个业务。与accounts表的联接用于检查列表的有效性 select listing.* from listing listing , account account where listing.account_id = account.id and listing.a

我有一个遗留innodb表,其中包含一个具有纬度/经度的业务。给定一个输入纬度/经度(低于51.2167/4.41667),查询将按距离(公里)的顺序返回第一个激活、启用、未删除的30个业务。与accounts表的联接用于检查列表的有效性

select 
    listing.*
from
    listing listing ,
    account account 
where
    listing.account_id = account.id 
    and listing.active = 1 
    and listing.approved = 1 
    and listing.deleted = 0 
    and listing.enabled = 1 
    and account.enabled = 1 
    and account.activated_by_user = 1 
group by
    listing.id
having
     111.222569*degrees(acos(sin(radians(listing.latitude))*sin(radians( 51.2167)) +cos(radians(listing.latitude))*cos(radians( 51.2167))*cos(radians(listing.longitude - 4.41667)))) < 250
order by
     111.222569*degrees(acos(sin(radians(listing.latitude))*sin(radians( 51.2167)) +cos(radians(listing.latitude))*cos(radians( 51.2167))*cos(radians(listing.longitude - 4.41667))))
limit 30;

非常感谢您的帮助。

您可能想看看。不幸的是,您无法在任何非
几何体
类型的列上创建
空间
索引,因此,您至少需要向表中添加一列。

这需要很长时间,因为您的查询正在为50k行表中的每一行计算一次带有所有超越函数的大圆距离公式(包括排序时两次)

你能限制你搜索的距离吗?您可能已经注意到,大多数store finder web应用程序都有一个下拉菜单项,可以选择“5英里以内”、“10英里以内”等等

如果你能做到这一点,你应该在你的搜索中添加一个WHERE子句,并通过在你的纬度列上放置一个索引来优化它。假设您使用值RANGELIMIT作为搜索范围限制,以英里为单位

试试这个条款

WHERE LISTING.LATITUDE BETWEEN LOCATION.LATITUDE - (RANGELIMIT * 1.1508/60) 
                           AND LOCATION.LATITUDE + (RANGELIMIT * 1.1508/60)
这是因为一海里几乎完全等于一分钟(1/60)的纬度。1.1508系数将海里转换为法定英里

我建议的子句将使用纬度索引来缩小搜索范围,并且计算大圆距离的频率将大大降低


您还可以包含一个关于经度的BETWEEN子句。但根据我的经验,只需在搜索之间选择一个纬度,就能得到非常好的结果。

你好,奥利,谢谢你的明确解释。然而,到目前为止,我没有太多的运气通过你的建议缩小搜索范围来显著加快查询速度,即使使用纬度索引。我将进行更多的实验。提高速度的是更改select:select id、纬度、经度而不是select listing。*并随后对listing表执行查询以获取其余数据。我想知道是否值得创建一个单独的MyISAM表来存储列表id和几何体以用于搜索。有人对这些空间索引的速度有经验吗?我不确定是否有可能建立一个能够计算出二维距离的索引。索引的目的是以有序的方式预加载搜索的某些方面。条件之间的经度计算方法是否与纬度计算方法相同?
WHERE LISTING.LATITUDE BETWEEN LOCATION.LATITUDE - (RANGELIMIT * 1.1508/60) 
                           AND LOCATION.LATITUDE + (RANGELIMIT * 1.1508/60)