如果我添加一个where,查询会变慢

时间:2016-11-14 07:29:17

标签: mysql

SELECT a.emp_id,s.name, s.department,s.register, z.Compoff_Count as Extra,  ifnull(COUNT(DISTINCT TO_DAYS(a.punchdate)),0) as Monthly_Count
FROM machinedata a left join

(SELECT a.emp_id, ifnull(COUNT(DISTINCT TO_DAYS(a.punchdate)),0) as Compoff_Count
FROM machinedata a 
RIght  JOIN time_dimension c on c.db_date = a.punchdate 
where (  year(c.db_date) = 2016 and  month(c.db_date) = 8   and (c.holiday_flag = 't' or c.weekend_flag ='t' ))
GROUP BY a.emp_id) Z
on z.emp_id = a.emp_id
RIght  JOIN time_dimension c on c.db_date = a.punchdate 
left join emp s on s.emp_id = a.emp_id  

where (year(c.db_date) = 2016 and  month(c.db_date) = 8  and c.holiday_flag = 'f' and c.weekend_flag ='f' )
GROUP BY emp_id

以上查询工作正常..但如果我添加s.department ='是'在查询占用超过40秒的最后一个。

我该怎么做才能提高查询性能?

1 个答案:

答案 0 :(得分:0)

您的初始查询可以简化我相信使用“条件聚合”将case表达式放在count()函数中。这避免了重复的数据传播和对派生表的不必要的连接。

您还应该避免在数据上使用函数来适应where子句条件,即,而不是YEAR()和MONTH()只使用日期边界。这允许在查询执行中使用日期列上的索引。

我不确定你是否真的需要使用TO_DAYS(),但我怀疑它也不需要。

SELECT
      a.emp_id
    , s.name
    , s.department
    , s.register
    , COUNT(DISTINCT CASE WHEN (c.holiday_flag = 't' OR
            c.weekend_flag = 't') THEN c.db_date END) AS Compoff_Count
    , COUNT(DISTINCT CASE WHEN NOT (c.holiday_flag = 't' OR
            c.weekend_flag = 't') THEN a.punchdate END) AS Monthly_Count
FROM time_dimension c
LEFT JOIN machinedata a ON c.db_date = a.punchdate
LEFT JOIN emp s ON a.emp_id = s.emp_id
WHERE c.db_date >= '2016-08-01'
      AND c.db_date < '2016-09-01'
GROUP BY
      a.emp_id
    , s.name
    , s.department
    , s.register

如果重新编写产生正确的结果,那么您可以尝试将和s.department ='yes'添加到where子句中以评估影响。如果它仍然大大慢,那么得到解释计划并将其添加到问题中。缓慢的最可能原因是缺乏指数但没有解释计划则无法确定。

请注意,这个建议就是这样;并准备没有样本数据和预期结果。