Mysql在条件检查之间有多个条件?有没有办法优化此查询?

时间:2016-08-19 12:31:23

标签: php mysql subquery query-optimization between

我正在处理报告生成应用程序,我正在使用基于用户操作的 PHP 生成查询。现在我根据工作人员的经验查询细节,有多个选择选项的可能性。结果来自加入5个表和子查询,我的查询正常工作并获取确切结果

第一种情景: 雇用员工总共15至20年经验

查询

SELECT sd.staff_ref_id AS staff_code,
       sd.sur,
       sd.staff_name AS Name,
       sq.degree AS Qualification,
       sd.designation,
       d.department_name,
       TIMESTAMPDIFF(MONTH, s.join_date, CURDATE()) AS rec_exp_months,
       sum(spe.years) AS p_exp_yrs,
       sum(spe.months) AS p_exp_months
FROM staff_details sd
LEFT JOIN
  (SELECT s.staff_id,
          group_concat(sq.degree) AS degree
   FROM staff_details s,
        staff_qualification sq
   WHERE s.staff_id = sq.staff_id
   GROUP BY sq.staff_id
   ORDER BY sq.row_num)sq ON sd.staff_id = sq.staff_id
LEFT JOIN staff_department s ON s.staff_id = sd.staff_id
LEFT JOIN department d ON d.department_id =s.depart_id
LEFT JOIN staff_previous_experience spe ON spe.staff_id = sd.staff_id
WHERE ((TIMESTAMPDIFF(MONTH,sd.join_date,CURDATE())) +
           (SELECT (sum(sqn.years)*12) + sum(sqn.months)
            FROM staff_previous_experience sqn
            WHERE sqn.staff_id=sd.staff_id
            GROUP BY sqn.staff_id) BETWEEN 120 AND 180)
GROUP BY staff_ref_id,
         sd.sur,
         sd.staff_name,
         sd.designation,
         d.department_name,
         sq.degree,
         s.join_date

第二种情景:让工作人员在总体经验10到15年和15到20年之间经历

查询

SELECT sd.staff_ref_id AS staff_code,
       sd.sur,
       sd.staff_name AS Name,
       sq.degree AS Qualification,
       sd.designation,
       d.department_name,
       TIMESTAMPDIFF(MONTH, s.join_date, CURDATE()) AS rec_exp_months,
       sum(spe.years) AS p_exp_yrs,
       sum(spe.months) AS p_exp_months
FROM staff_details sd
LEFT JOIN
  (SELECT s.staff_id,
          group_concat(sq.degree) AS degree
   FROM staff_details s,
        staff_qualification sq
   WHERE s.staff_id = sq.staff_id
   GROUP BY sq.staff_id
   ORDER BY sq.row_num)sq ON sd.staff_id = sq.staff_id
LEFT JOIN staff_department s ON s.staff_id = sd.staff_id
LEFT JOIN department d ON d.department_id =s.depart_id
LEFT JOIN staff_previous_experience spe ON spe.staff_id = sd.staff_id
WHERE ((TIMESTAMPDIFF(MONTH,sd.join_date,CURDATE())) +
           (SELECT (sum(sqn.years)*12) + sum(sqn.months)
            FROM staff_previous_experience sqn
            WHERE sqn.staff_id=sd.staff_id
            GROUP BY sqn.staff_id) BETWEEN 120 AND 180
         OR (TIMESTAMPDIFF(MONTH,sd.join_date,CURDATE())) +
           (SELECT (sum(sqn.years)*12) + sum(sqn.months)
            FROM staff_previous_experience sqn
            WHERE sqn.staff_id=sd.staff_id
            GROUP BY sqn.staff_id) BETWEEN 180 AND 240)
GROUP BY staff_ref_id,
         sd.sur,
         sd.staff_name,
         sd.designation,
         d.department_name,
         sq.degree,
         s.join_date

注意:上面突出显示的区域,我正在检查总体验,我将数据库的输入和结果转换为月份并检查条件

问题:Darken Area是从php生成的查询,我在查询之间使用 ...基于从经验字段中选择了多少选项,查询之间的 将自动生成..
有什么方法可以优化它吗?
在多个条件的查询中是否可以选择使用选项...?

我的查询执行时间为0.0663秒

等待回应,建议和建议 提前致谢

1 个答案:

答案 0 :(得分:1)

感觉这会产生与第一个WHERE相同的效果:

WHERE sd.join_date >= CURDATE() - INTERVAL 180 MONTH
  AND sd.join_date  < CURDATE() - INTERVAL 120 MONTH

并拥有INDEX(join_date)

如果是这样,那就更加简单,必须更快。

突出显示的子查询中的GROUP BY是不必要的。

由于ORDER BY row_numGROUP BY可能无效并被忽略。

LEFT JOIN之后的派生表中似乎没有必要。

为什么单独计算BETWEEN 120 AND 180BETWEEN 180 AND 240?似乎他们可以合并在一起。

如果速度不快,那么请在评论中进行清理,然后重新开始。请为每个表提供SHOW CREATE TABLE