我有一个高级 MySQL 搜索,它正在运行基于纬度和经度的半径搜索。 上次我构建这样的系统时,查询速度存在很多问题。 我一直在阅读周围的内容,我注意到有些人会在选择中包含它。
SELECT *, (6271 * acos(cos(radians('".$lat."')) * cos(radians(lat)) * cos( radians(long) - radians('".$lng."')) + sin(radians('".$lat."')) *
sin(radians(lat))))
AS distance
FROM carpark HAVING distance < 15 ORDER BY distance LIMIT 0 , 10";
或者也可以在 where 子句中运行它。
Where ( 6371 * ACOS( COS( RADIANS(".$lat.") ) * COS( RADIANS( grt32sg32u_PostCodeData.lat ) )
* COS( RADIANS(PostCodeData.lon) - RADIANS(".$lon.")) + SIN(RADIANS(".$lat."))
* SIN( RADIANS(PostCodeData.lat)))) <= 15";
那么哪个更快呢?它们的速度相同还是有区别? 还有其他方法可以优化此查询吗?
最佳答案
我不是地理专家,但如果我们假设您有一个相当大的数据库,那么您将对最终距离 > 15 的记录进行大量数学计算。
我不知道哪个(SELECT
中的子句或 WHERE
中的子句)更快,但我认为您会看到更大的性能提升限制任一子句返回的结果
你能将其简化为两个查询吗?不计算半径,怎么样(下面的伪代码)
where PostCodeData.lat between $lat - radius and $lat + radius
这应该运行得很快 - 行上没有数学运算,纬度和经度可能已建立索引。
然后您可以对此结果运行半径查询。希望您不会看到数千行,而会看到不到十几行。
在正方形中搜索点比在圆中搜索点要快得多。这里的技巧是将搜索范围缩小到最小的封闭正方形,然后使用半径(如果您确实需要它)来消除角落中的点。
关于一个不相关但重要的说明,请检查您的代码 possible SQL Injection issues .
关于Mysql 在 select 或 where 子句中使用搜索/过滤语句会更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18968559/