Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 极慢的查询_Mysql_Sql_Query Performance - Fatal编程技术网

Mysql 极慢的查询

Mysql 极慢的查询,mysql,sql,query-performance,Mysql,Sql,Query Performance,下面是一个运行时间超过30秒的查询。基于我运行过的类似查询,我看不出阻塞在哪里。我唯一的想法是将job用户id加入到job_申请者的用户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_

下面是一个运行时间超过30秒的查询。基于我运行过的类似查询,我看不出阻塞在哪里。我唯一的想法是将job用户id加入到job_申请者的用户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

使用
存在

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;
这将防止所有笛卡尔积和最终删除重复项

我建议在以下方面建立索引:

  • 用户(姓氏、用户id)
  • employee\u access(用户id,访问id)
  • 确认(用户id、访问id)
  • 求职者(用户id、流程级别、职位id)
  • 作业(作业id、访问id)

使用
存在

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;
这将防止所有笛卡尔积和最终删除重复项

我建议在以下方面建立索引:

  • 用户(姓氏、用户id)
  • employee\u access(用户id,访问id)
  • 确认(用户id、访问id)
  • 求职者(用户id、流程级别、职位id)
  • 作业(作业id、访问id)

这应该是可行的。这在概念上与Gordon的答案相似,但我对相关子查询有一种近乎病态的不信任


这应该行得通。这在概念上与Gordon的答案相似,但我对相关子查询有一种近乎病态的不信任


还有另一种方法。这样做的好处是首先收集
用户ID列表
,然后进入
用户
,查看其他列:

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
索引:

employee_access: INDEX(access_id, user_id)  -- (covering)
confirmation:    INDEX(access_id, user_id)  -- (covering)
job:             INDEX(access_id, job_id)  -- (covering)
job_applicants:  INDEX(process_level, job_id, user_id)  -- (covering)
users:  PRIMARY KEY(user_id)

看看这是否会缩短剩下的8秒钟。

还有另一种方法。这样做的好处是首先收集
用户ID列表
,然后进入
用户
,查看其他列:

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
索引:

employee_access: INDEX(access_id, user_id)  -- (covering)
confirmation:    INDEX(access_id, user_id)  -- (covering)
job:             INDEX(access_id, job_id)  -- (covering)
job_applicants:  INDEX(process_level, job_id, user_id)  -- (covering)
users:  PRIMARY KEY(user_id)

看看这是否会缩短剩下的8秒钟。

您的桌子有多大?它们是如何编制索引的?你也可以发布查询的解释吗。(只需在选择并运行查询前加上“EXPLAIN”)所有这些表中的主键是
user\u id
?如果没有,是否索引?您的表有多大?它们是如何编制索引的?你也可以发布查询的解释吗。(只需在选择并运行查询前加上“EXPLAIN”)所有这些表中的主键是
user\u id
?如果没有,它是索引的吗?在看到您的答案后,我现在明白了为什么原始查询使用外部联接——它只需要处理其他一个表中的ID匹配。在不更新索引的情况下,这个更新的查询缩短了20秒(8秒对28秒)。非常感谢。一旦更新的索引到位,将对速度留下评论。对于
求职者
我会使用索引
(用户id、流程级别、流程id)
,因为在使用
工作id
加入下一个表之前,您首先要按
流程级别
进行筛选。很好。在看到您的答案后,我现在明白了为什么原始查询使用外部联接——它只需要处理其他一个表中的ID匹配。在不更新索引的情况下,这个更新的查询缩短了20秒(8秒对28秒)。非常感谢。一旦更新的索引到位,将对速度留下评论。对于
求职者
我会使用索引
(用户id、流程级别、流程id)
,因为在使用
工作id
加入下一个表之前,您首先要按
流程级别
进行筛选。接得好,确实是这样。这很快!的确如此。这很快!