Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.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_Sql_Query Optimization_Geospatial_Latitude Longitude - Fatal编程技术网

在半径MySQL(经纬度)内查找大型表中点的最快方法是什么

在半径MySQL(经纬度)内查找大型表中点的最快方法是什么,mysql,sql,query-optimization,geospatial,latitude-longitude,Mysql,Sql,Query Optimization,Geospatial,Latitude Longitude,目前我有几个表有100k+行。我正试图查找如下数据 SELECT *, SQRT(POW(69.1 * (latitude - '49.1044302'), 2) + POW(69.1 * ('-122.801094' - longitude) * COS(latitude / 57.3), 2)) AS distance FROM stops HAVING distance < 5 ORDER BY distance limit 100 但目前这种方法速度慢,负载高。有些查询需要20多

目前我有几个表有100k+行。我正试图查找如下数据

SELECT
*, SQRT(POW(69.1 * (latitude - '49.1044302'), 2) + POW(69.1 * ('-122.801094' - longitude) * COS(latitude / 57.3), 2)) AS distance
FROM stops
HAVING distance < 5
ORDER BY distance limit 100
但目前这种方法速度慢,负载高。有些查询需要20多秒才能完成


如果有人知道更好的优化方法,那就太好了。

首先,如果你有很多地理空间数据,你应该使用mysql的地理空间扩展,而不是像这样的计算。这样可以加快许多查询的速度,而不必像上面那样编写冗长的查询


使用比较或创建具有感兴趣半径以及ST_in的几何体可能会得到很好的结果,并且可能比当前速度快得多。然而,实现这一点的最佳和最快的方法还没有在mysql中实现。

空间索引肯定取决于mysql版本。我们的站点也搜索lat/lons,但我们使用的是MySQL 5.1的旧版本,没有空间索引。您的查询与我们的查询类似,但我们的查询基于弧度。根据您的具体需求,您可以根据自己的实际情况进行优化

一定要从数据库查询中删除sqrt,它必须为每一行进行计算-仅在向用户显示实际距离时在末尾进行计算-还要将距离<5到<25的距离平方。Sqrt非常昂贵,而且很容易移动到不需要计算的地方。 取消引用lat/lon'49.1044302',使其严格为int,并在查询外部执行lat/lon类型检查。这不会加快它的速度,但会防止由于lat/lon变量中虚假的尾随空格而导致错误的强制转换。 将5转换为每个方向上的实际lat/lot度差+/5,以生成框的极限范围。将其添加到查询的where部分-此限制将使您获得一个大大减少的几乎精确的结果行集-基本上,lat和lon上的x和y+/-范围是结果的上限-计算的对角线只会对结果及其距离产生细微差别。 将尽可能多的数学移到select和where之外——它必须扫描整个表,并创建一个临时表,对每一行进行计算,以给出这些结果。查询中的许多数学运算可以转换为常量。 通过降低lat/lon复制到另一个字段的分辨率,或者乘以10或100,转换为整数并在该字段上添加索引,并在其中使用带+/-边界的字段,进一步加快选择框的行缩减速度,至少到那时,它将能够使用一个键-mysql可以减少和这些结果快得多。
至少我们是这样做的。

49.1044302不是整数。一个数字就可以了。此外,在比较数字列时,引号并不重要。边界框3是这个答案中最有效的部分-假设您有INDEXlatitude或IndexLongtude。不正确。虽然float不是int,但他应该乘以纬度或经度并降低精度,以便从数值索引中获益,最好是整数索引。引用也很重要,但不是因为你所暗示的原因。如果一个空格以某种方式将其转换为lat或long变量字符串,那么mysql优化器不会将$var转换为numeric。通过保留引号,任何可能来自用户输入的错误空格都将以sql本身的空格结束,并变得无害。不要这么快按下白痴按钮。此外,即使你没有lat和lon的索引,在where子句中指定一个范围也会减少表格扫描中产生的结果行集,并减少几何距离的计算。我知道这些观点是正确的,因为尽管你的网站上列出了代码,我还是不得不在mysql版本3.23.28中对大表进行lan/lot查询。第一个候选版本。它很复杂:您是否按照建议检查了mysql地理空间类型?添加一个空间索引,使用空间函数获得一组粗略匹配,并且仍然在WHERE子句中使用当前谓词以及空间分析函数也是可行的。优化器会自动知道,使用空间索引在大致正确的区域中查找候选匹配是聪明的,然后进一步缩小它们的范围,使用where根据非空间谓词过滤匹配行,在保持现有逻辑精度的同时提供更好的性能。Spatial无疑是前进的路径。原始查询的公式也可以在存储函数中由内而外重写,该函数计算并返回表示距离目标位置x的边界框的多边形,因为iirc ST_距离不是haversine,而是平面的。