I have a problem. I have a sql query. query is so slow when i use order by distance. But if i dont use order by distance then query is fast. My query is:
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
Is there an alternative query for this query. Thank you.
It's your use of HAVING instead of a WHERE contraint. Your construct is syntactically equivalent of:
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
Now do you see why it can run a lot slower?
Something like:
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
if you precompute the AAAA ... DDDD to be the bounding rectangle and you have non-unique indexes on lat and long. This will at least limit the rows to be read as well as those to be sorted
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.