I have a mysql select statement to search on my site that has performance issues when the site is really busy. The query below searches for ads from a table with more than 100 thousand records, within 25 miles of a given lat value and longer and sorted by distance. The number of miles may vary as the user selects it.
The problem is that I think it is slow because it makes calculations for all entries in the table, and not for those that are within 25 miles of the lat and bosom. Is it possible to modify this request so that where the offer selects only advertisements within 25 miles? Ive read about bounding boxes and spatial indexes, but I'm not sure how to apply them to this query, I need to add a where clause that selects records with a radius of 25 miles from lat and lon, how to do it?
SELECT
adverts.*,
round(sqrt((((adverts.latitude - '53.410778') * (adverts.latitude - '53.410778')) * 69.1 * 69.1) + ((adverts.longitude - '-2.97784') * (adverts.longitude - '-2.97784') * 53 * 53)), 1) as distance
FROM
adverts
WHERE
(adverts.type_id = '3')
HAVING
DISTANCE < 25
ORDER BY
distance ASC
LIMIT 120,10
Edit: updated to include the table schema, note that the table is more complex, so there is a query, but I deleted things that are not needed for this problem.
CREATE TABLE `adverts` (
`advert_id` int(10) NOT NULL AUTO_INCREMENT,
`type_id` tinyint(1) NOT NULL,
`headline` varchar(50) NOT NULL,
`description` text NOT NULL,
`price` int(4) NOT NULL,
`postcode` varchar(7) NOT NULL,
`latitude` float NOT NULL,
`longitude` float NOT NULL,
PRIMARY KEY (`advert_id`),
KEY `latlon` (`latitude`,`longitude`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
mysql, 67900, , 25 , "Using where; Using filesort".
0,3 , , - .