我有一个查询运行良好,但速度有点慢。经过一番研究后,我发现使用查询的 HAVING 部分会导致速度变慢。有没有办法在不使用 HAVING 的情况下实现这一目标?
$query = sprintf("SELECT p.*,( 3959 * acos( cos( radians('%s') ) *
cos( radians( `loclat` ) ) * cos( radians( `loclong` ) - radians('%s') )
+ sin( radians('%s') ) * sin( radians( `loclat` ) ) ) ) AS distance
FROM postLocation as pl, posts as p
WHERE pl.pid = p.id %s %s %s
HAVING distance < '%s'
ORDER BY p.utc DESC, distance ASC LIMIT 0 , %s ",
$loclat,
$loclong,
$loclat, $status, $type, $start,
$radius, $limit);
我有 sprintf 函数可以使用,同时仍在处理我的查询的最终版本.. 使我现在更容易修改东西等。所以我知道有一个函数会增加时间.. 主要关注查询本身...如果还有其他任何严重错误,我会洗耳恭听,但我相信 HAVING 部分是麻烦制造者。
提前致谢!
最佳答案
罪魁祸首不是 HAVING
子句本身,而是您用来计算距离的所有超越函数(sin、cos、acos)。它们在计算上非常昂贵。
您可以尝试使用以下方法获得距离的近似值:
sqrt(x * x + y * y)
where x = 69.1 * (lat2 - lat1)
and y = 53.0 * (lon2 - lon1)
您可以通过添加余弦函数来提高这种近似距离计算的准确性:
sqrt(x * x + y * y)
where x = 69.1 * (lat2 - lat1)
and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3)
来源:http://www.meridianworlddata.com/Distance-Calculation.asp
近似值更快且相当准确,尤其是对于小距离。
您要么这样做,要么获得更好的服务器。
关于PHP/MySQL 在不使用 HAVING 的情况下执行距离相关搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7356426/