我有一个 mysql select 语句,用于在我的网站上进行搜索,当网站变得非常繁忙时,它会出现性能问题。下面的查询从具有超过 10 万条记录的表中搜索广告,在给定纬度和经度的 25 英里范围内,并按距离排序。里程数可以不同,因为它是由用户选择的。
问题是我认为它很慢,因为它对表中的所有记录进行计算,而不是对纬度和经度 25 英里范围内的记录进行计算。是否可以修改此查询,以便 where 子句仅选择 25 英里内的广告?我已经阅读了有关边界框和空间索引的信息,但我不确定如何将它们应用于此查询,我是否需要添加一个 where 子句来选择经纬度半径 25 英里的记录,我该怎么做?
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
编辑:更新以包括表模式,请注意表更复杂,查询也是如此,但我已经删除了这个问题不需要的东西。
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 英里半径内的要多得多,额外的设置为“使用 where;使用文件排序”。
查询需要 0.3 秒,这真的很慢,尤其是当网站每秒收到大量请求时。