PHP/MySQL Perform a Distance Related Search WITHOUT using HAVING
I have a query that is working just fine however it is a bit on the slow-side. After researching a bit I found that using the HAVING part of my query is causing a slow-down. Is there a way to pull this off WITHOUT using the HAVING piece?
$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,
开发者_Python百科 $radius, $limit);
I have the sprintf function to use while still working on the final versoin of my query.. makes it easier for me currently to modify things etc. So I know having a function would add time.. primarily focusing on the query itself... if there is anything else HUGELY wrong I'm all ears but I believe the HAVING part is the trouble maker.
Thanks in advance!
The culprit is not the HAVING
clause per se, but all the transcendental functions (sin, cos, acos) you are using to calculate distance. They are very computationally expensive.
You can try to get an approximation of the distance by using:
sqrt(x * x + y * y)
where x = 69.1 * (lat2 - lat1)
and y = 53.0 * (lon2 - lon1)
You can improve the accuracy of this approximate distance calculation by adding the cosine function:
sqrt(x * x + y * y)
where x = 69.1 * (lat2 - lat1)
and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3)
source: http://www.meridianworlddata.com/Distance-Calculation.asp
The approximations are much faster and fairly accurate, especially for small distances.
Either you do that, or get a better server.
The real solution is to use a database with geo-spacial datatype support (like PostGIS).
精彩评论