对于给定的经度,纬度和半径,我应该从具有500&#39,000个数据记录的数据库中选择averagePrice,numberOfListings,....
(id)1(select_type)SIMPLE(表)数据库(分区)NULL(类型)ALL(possible_keys)NULL(键)NULL(key_len)NULL(ref)NULL(行)623612(已过滤)100.00(额外) NULL
CREATE TABLE `database` (
`id` varchar(255) DEFAULT NULL,
`longitude` varchar(255) DEFAULT NULL,
`latitude` varchar(255) DEFAULT NULL,
`price` int(11) DEFAULT NULL,
`bathrooms` int(11) DEFAULT NULL,
`bedrooms` int(11) DEFAULT NULL,
`person_capacity` int(11) DEFAULT NULL,
`rev_count` int(11) DEFAULT NULL,
KEY `hosting_id` (`hosting_id`),
KEY `price` (`price`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
选择不分组的查询。
SELECT
avg(price) as averagePrice,
count(*) as numberOfListings,
min(price) as minprice,
max(price) as maxprice,
avg(bedrooms) as averagebedrooms,
avg(bathrooms) as averagebathrooms,
avg(person_capacity) as averagepc,
avg(rev_count) as averageReviews,
avg(time_appartement) as averageDateHasBeenListed
FROM
(SELECT
r.*,
( 6371 * acos( cos( radians(37.774929) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-122.419416) ) + sin( radians(37.774929) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM
`database` r ) r
WHERE
distance <= 25
AND price >= 10
ORDER BY
distance ASC
这适用于查询时间约1秒。现在我接下来的步骤是将子查询与id分组,并为每个id选择平均价格,卧室,浴室,person_capacity,rev_count和time_appartement。
SELECT
avg(price) as averagePrice,
count(*) as numberOfListings,
min(price) as minprice,
max(price) as maxprice,
avg(bedrooms) as averagebedrooms,
avg(bathrooms) as averagebathrooms,
avg(person_capacity) as averagepc,
avg(rev_count) as averageReviews,
avg(time_appartement) as averageDateHasBeenListed
FROM
(SELECT
id,
avg(r.price) as price,
avg(r.bedrooms) as bedrooms,
avg(r.bathrooms) as bathrooms,
avg(r.person_capacity) as person_capacity,
avg(r.rev_count) as rev_count,
avg(r.time_appartement) as time_appartement,
( 6371 * acos( cos( radians(37.774929) ) * cos( radians( ANY_VALUE(`latitude` )) ) * cos( radians( ANY_VALUE(`longitude`) ) - radians(-122.419416) ) + sin( radians(37.774929) ) * sin( radians( ANY_VALUE(`latitude`) ) ) ) ) AS distance
FROM
`database` r
GROUP BY
r.id ) r
WHERE
distance <= 25
AND price >= 10
ORDER BY
distance ASC
它有效,但问题是这个查询的时间大约是7秒。
是否可以减少时间? 谢谢你的回复。
答案 0 :(得分:0)
您可以将价格条件移至子查询。
另外,请确保您拥有ID和价格索引
答案 1 :(得分:0)
latitude
和longitude
比VARCHAR(255)
更糟糕。对于家庭来说,这应该是好的:
latitude DECIMAL(6,4),
longitude DECIMAL(7,4)
什么样的id
需要VARCHAR(255)
?
你期待数百万或数十亿的卧室吗?使用TINYINT UNSIGNED
(1个字节,范围为0..255)可以提高效率。
没有PRIMARY KEY
;这对InnoDB来说很糟糕。
AVG(AVG(...))在数学上是不好的。
您的子查询意味着有多个行具有相同的id
;发生了什么事?
修复这些内容,阅读&#34;边界框&#34;然后再回来寻求更多帮助/滥用。