我有一个高级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
这应该运行得很快 - 行上没有数学,并且 lat 和 lon 可能被索引。
然后,您可以对此结果运行半径查询。 希望您不会查看数千行,而是查看不到十几行。
在正方形中搜索点比在圆中搜索点要快得多。 这里的诀窍是将搜索范围缩小到最小的封闭正方形,然后使用半径(如果您确实需要它(来消除角落中的点。
在不相关但重要的说明中,请查看您的代码是否存在可能的 SQL 注入问题。