极慢的查询

时间:2017-10-20 20:15:58

标签: mysql sql query-performance

以下是一个需要30多秒才能运行的查询。基于我运行的类似查询,我无法看到这里的停滞位置。我唯一的想法是将作业用户ID加入job_applicants用户ID,但需要映射它们。

SELECT DISTINCT u.user_id, u.first_name, u.last_name FROM users u
LEFT OUTER JOIN employee_access ea ON ea.user_id = u.user_id
LEFT OUTER JOIN confirmation c ON c.user_id = u.user_id
LEFT OUTER JOIN job_applicants a ON a.user_id = u.user_id
LEFT OUTER JOIN job j ON j.job_id = a.job_id
WHERE ea.access_id = 4 OR c.access_id = 4 OR (a.process_level = 0 AND j.access_id = 4) 
ORDER BY u.last_name asc

3 个答案:

答案 0 :(得分:5)

使用exists

select u.*
from users u
where exists (select 1
              from employee_access ea 
              where ea.user_id = u.user_id and ea.access_id = 4
             ) or
      exists (select 1
              from confirmation c 
              where c.user_id = u.user_id and c.access_id = 4
             ) or
      exists (select 1
              from job_applicants a join
                   job j 
                   on j.job_id = a.job_id
              where a.user_id = u.user_id and
                    a.process_level = 0 AND j.access_id = 4
             )
order by u.last_name;

这将阻止所有笛卡尔产品和最终删除重复项。

我建议使用索引:

  • users(last_name, user_id)
  • employee_access(user_id, access_id)
  • confirmation(user_id, access_id)
  • job_applicants(user_id, process_level, job_id)
  • job(job_id, access_id)

答案 1 :(得分:2)

又一种方法。这样做的好处是首先收集express.use('*',(req,res,next) =>{ if (req.method == "OPTIONS") { res.status(200); res.send(); }else{ next(); } }); 然后列表到达其他列的user_ids

users

索引:

SELECT  u.user_id, u.first_name, u.last_name
    FROM  users u
    JOIN (
        ( SELECT user_id FROM employee_access WHERE access_id = 4 )
        UNION DISTINCT
        ( SELECT user_id FROM confirmation    WHERE access_id = 4 )
        UNION DISTINCT
        ( SELECT a.user_id 
              FROM job_applicants a 
              JOIN job j  USING(job_id)
              WHERE a.process_level = 0
                AND j.access_id = 4 )
    ) AS x USING(user_id)
    ORDER BY u.last_name ASC

看看这是否会减少剩下的8秒钟中的大部分时间。

答案 2 :(得分:1)

这应该有效。它在概念上类似于戈登的回答,但我对相关子查询存在边缘病态的不信任。

SELECT DISTINCT u.user_id, u.first_name, u.last_name 
FROM users u
WHERE u.user_id IN (SELECT user_id FROM employee_access WHERE access_id = 4)
   OR u.user_id IN (SELECT user_id FROM confirmation WHERE access_id = 4)
   OR u.user_id IN (
        SELECT a.user_id 
        FROM job_applicants a 
        INNER JOIN job j ON j.job_id = a.job_id
        WHERE a.process_level = 0 AND j.access_id = 4
      )
ORDER BY u.last_name asc