查询需要很长时间才能执行

时间:2014-11-02 12:51:03

标签: mysql

我有以下查询,我使用betwen运算符来获取具有特定数字之间年龄的记录,但查询花费了大量时间来显示结果,其中超过5分钟它还在运行

SELECT
  *,
  (SELECT COUNT(*)
   FROM users
   WHERE
     1=1 OR
     LOWER(age) BETWEEN 18 AND 20 OR
     LOWER(age) BETWEEN 20 AND 25 OR
     LOWER(age) BETWEEN 25 AND 30 OR
     LOWER(age) BETWEEN 30 AND 35
  ) AS totalcount
FROM users, states, countries, user_types, media
WHERE
  users.id_user_type = user_types.id AND
  users.id_state = states.id AND
  users.id_country = countries.id AND
  media.id_user = users.id AND
  media.profile_photo = 1 AND
  users.id_user_type = 3 OR
  LOWER(age) BETWEEN 18 AND 20 OR
  LOWER(age) BETWEEN 20 AND 25 OR
  LOWER(age) BETWEEN 25 AND 30 OR
  LOWER(age) BETWEEN 30 AND 35
ORDER BY users.id 

令人不安的部分是:

LOWER(age) BETWEEN 18 AND 20 OR
LOWER(age) BETWEEN 20 AND 25 OR
LOWER(age) BETWEEN 25 AND 30 OR
LOWER(age) BETWEEN 30 AND 35

2 个答案:

答案 0 :(得分:1)

避免使用您拥有的or子句(这没有意义)。你的查询可能正在做很多CROSS JOIN操作,这就是为什么它花了太长时间(你的结果集是巨大的)。

 select *,
        (
            select count(*) 
              from users 
             where 1=1 
                or lower(age) between 18 and 20 
                or lower(age) between 20 and 25 
                or lower(age) between 25 and 30 
                or lower(age) between 30 and 35
        ) as totalcount 
   from users, states, countries, user_types, media 
  where users.id_user_type = user_types.id 
    and users.id_state = states.id 
    and users.id_country = countries.id 
    and media.id_user = users.id 
    and media.profile_photo = 1 
    and users.id_user_type = 3 
  order by users.id 

此外,我们还不清楚您要使用此查询完成的操作。

回答这些问题可能会对我们有所帮助:

  1. age列类型
  2. 的内容
  3. 您对内部查询的期望是什么

答案 1 :(得分:0)

您的or语句分析不正确。你需要括号:

FROM users, states, countries, user_types, media
WHERE (users.id_user_type = user_types.id AND
       users.id_state = states.id AND
       users.id_country = countries.id AND
       media.id_user = users.id AND
       media.profile_photo = 1 AND
       (users.id_user_type = 3 OR
        LOWER(age) BETWEEN 18 AND 20 OR
        LOWER(age) BETWEEN 20 AND 25 OR
        LOWER(age) BETWEEN 25 AND 30 OR
        LOWER(age) BETWEEN 30 AND 35
       )

如上所述,您的查询必须在五个表中执行完整的笛卡尔积,然后进行一些奇怪的过滤。

如果使用正确的join语法,这基本上不是问题。简单规则:永远不要在from子句中使用逗号。

此外,查询似乎没有意义。为什么要将age存储为字符串(使用lower()建议?那么,为什么要将这些与整数进行比较?为什么要将连续范围分成四个不同的比较,而不是仅仅说age between 18 and 35