【问题标题】:NOT IN subquery takes too long to executeNOT IN 子查询执行时间过长
【发布时间】:2015-05-21 06:25:17
【问题描述】:

如何优化此查询以获得相同的结果,而无需花费很长时间? NOT IN 子查询需要很长时间。

SELECT DISTINCT EmployeeId FROM employees
    WHERE 
    status = 'Active' 
    && BranchId = '2' 
    && NOT EXISTS (
      SELECT * FROM attendance
      WHERE
      employees.EmployeeId = attendance.EmployeeId 
      && attendance.AttendanceDate = '2015-01-20'
    )
  )

SELECT EmployeeId FROM employees 
    WHERE 
    status = 'Active' 
    && BranchId = '2' 
    && NOT IN (
      SELECT EmployeeId FROM attendance WHERE AttendanceDate='2015-01-20'
    )

【问题讨论】:

    标签: mysql mysql-slow-query-log


    【解决方案1】:

    这是您查询的另一个版本

    select
    distinct e.EmployeeId FROM employees e
    left join attendance a on e.EmployeeId = a.EmployeeId and a.AttendanceDate = '2015-01-20'
    where
    e.status='Active' 
    and e.BranchId= '2' 
    and a.EmployeeId is null
    

    您还需要在表上应用一些索引

    alter table employees add index st_br_idx(status,BranchId);
    alter table AttendanceDate add index AttendanceDate_idx(AttendanceDate);
    

    如果 EmployeeId 是外键,则不需要添加索引,否则 索引还没有,您可能还需要以下内容

    alter table AttendanceDate add index EmployeeId_idx(EmployeeId);
    

    如果EmployeeIdemployees 中的主键,那么它已经被索引,如果没有并且没有被索引,你可能还需要为此添加索引

    alter table employees add index EmployeeId_idx(EmployeeId);
    

    您也可以在拥有上述索引后检查您的原始查询

    SELECT DISTINCT e.EmployeeId FROM employees e 
    WHERE 
    e.status='Active' 
    and e.BranchId= '2' 
    and NOT EXISTS (
      SELECT 1 FROM 
      attendance a WHERE e.EmployeeId = a.EmployeeId 
      and a.AttendanceDate='2015-01-20'
    )
    

    要分析查询使用explain select.. 并查看优化器如何使用索引 以及优化器为检索记录而可能扫描的行数

    【讨论】:

      猜你喜欢
      • 2017-07-12
      • 1970-01-01
      • 2019-12-28
      • 2012-03-11
      • 1970-01-01
      • 2011-07-06
      相关资源
      最近更新 更多