[英]How can i optimize my sql query?
我有个问题。 我有一个SQL查询。 当我使用按距离排序时,查询是如此缓慢。 但是,如果我不按距离使用顺序,则查询速度很快。 我的查询是:
SELECT id,groupname,lat,lon,is_public,firma_kat,title,
((ACOS(SIN(41.06775100000000 * PI() / 180) * SIN(lat * PI() / 180) +
COS(41.06775100000000 * PI() / 180) * COS(lat * PI() / 180) *
COS((29.00661300000000 - lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515)
AS distance
FROM `groups`
WHERE id NOT IN(222330, 14302, 178547, 178563, 178572, 178571, 178573, 222328,
222334, 222342, 222358, 222366, 222370, 222371, 222373, 222383,
222384, 222396, 222419, 222438, 222539, 222553, 222555, 222563,
222565, 222572, 222574, 222575, 222576, 222577, 222579, 222591,
222592, 222594, 222613, 222711, 222630, 222632, 222653, 222657,
222677, 222679, 222683, 222688, 222689, 222697, 222719, 222721,
222727, 222728, 222735, 222736, 222737, 222744, 222746, 222749,
222770, 222771, 222791, 222797, 222798, 222803, 222800, 222801,
222802, 222804, 222805, 222806, 222807, 222808)
HAVING distance <= '100'
ORDER BY distance ASC LIMIT 0,50
是否有该查询的替代查询。 谢谢。
这是您使用HAVING而不是WHERE约束。 您的构造在语法上等效于:
SELECT * FROM (
SELECT id,groupname,lat,lon,is_public,firma_kat,title,
((ACOS(SIN(41.06775100000000 * PI() / 180) * SIN(lat * PI() / 180) +
COS(41.06775100000000 * PI() / 180) * COS(lat * PI() / 180) *
COS((29.00661300000000 - lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515)
AS distance
FROM `groups`
WHERE id NOT IN(222330, 14302, 178547, 178563, 178572, 178571, 178573, 222328,
222334, 222342, 222358, 222366, 222370, 222371, 222373, 222383,
222384, 222396, 222419, 222438, 222539, 222553, 222555, 222563,
222565, 222572, 222574, 222575, 222576, 222577, 222579, 222591,
222592, 222594, 222613, 222711, 222630, 222632, 222653, 222657,
222677, 222679, 222683, 222688, 222689, 222697, 222719, 222721,
222727, 222728, 222735, 222736, 222737, 222744, 222746, 222749,
222770, 222771, 222791, 222797, 222798, 222803, 222800, 222801,
222802, 222804, 222805, 222806, 222807, 222808)
) AS grp
WHERE grp.distance <= '100'
ORDER BY grp.distance ASC LIMIT 0,50
现在您知道为什么它运行速度会慢很多吗?
就像是:
SELECT id,groupname,lat,lon,is_public,firma_kat,title,
((ACOS(SIN(41.06775100000000 * PI() / 180) * SIN(lat * PI() / 180) +
COS(41.06775100000000 * PI() / 180) * COS(lat * PI() / 180) *
COS((29.00661300000000 - lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515)
AS distance
FROM `groups`
WHERE id NOT IN(222330, 14302, 178547, 178563, 178572, 178571, 178573, 222328,
222334, 222342, 222358, 222366, 222370, 222371, 222373, 222383,
222384, 222396, 222419, 222438, 222539, 222553, 222555, 222563,
222565, 222572, 222574, 222575, 222576, 222577, 222579, 222591,
222592, 222594, 222613, 222711, 222630, 222632, 222653, 222657,
222677, 222679, 222683, 222688, 222689, 222697, 222719, 222721,
222727, 222728, 222735, 222736, 222737, 222744, 222746, 222749,
222770, 222771, 222791, 222797, 222798, 222803, 222800, 222801,
222802, 222804, 222805, 222806, 222807, 222808)
WHERE
long BETWEEN AAAA AND BBBB AND
lat BETWEEN BBBB AND DDDD AND
distance <= '100'
ORDER distance ASC LIMIT 0,50
如果将AAAA ... DDDD预计算为边界矩形, 并且在lat和long上具有非唯一索引。 这将至少限制要读取的行以及要排序的行
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.