简体   繁体   English

如何优化我的SQL查询?

[英]How can i optimize my sql query?

I have a problem. 我有个问题。 I have a sql query. 我有一个SQL查询。 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. 这是您使用HAVING而不是WHERE约束。 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? 现在您知道为什么它运行速度会慢很多吗?

Addendum 附录

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. 如果将AAAA ... DDDD预计算为边界矩形, 并且在lat和long上具有非唯一索引。 This will at least limit the rows to be read as well as those to be sorted 这将至少限制要读取的行以及要排序的行

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM