我该如何优化我的SQL查询?

时间:2014-07-08 09:19:01

标签: mysql sql sorting optimization

我有问题。我有一个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

是否有此查询的替代查询。谢谢。

1 个答案:

答案 0 :(得分:0)

这是你使用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上有非唯一索引。这至少会限制要读取的行以及要排序的行