条件检查之间的Mysql中有多个条件?有没有办法优化这个查询?

Posted

技术标签:

【中文标题】条件检查之间的Mysql中有多个条件?有没有办法优化这个查询?【英文标题】:More than one condition in Mysql Between Condition Checking? Is there any way to optimize this query? 【发布时间】:2016-08-19 12:31:23 【问题描述】:

我正在开发报告生成应用程序,我正在根据用户操作使用 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

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

问题:变暗区域是从 php 生成的查询,我使用 between 查询..根据从经验字段中选择了多少选项,between 查询会自动生成.. 有没有办法优化这个..? 在查询中是否有一个选项可以在选项之间使用...?

我的查询执行时间是 0.0663 秒

等待回复、建议和建议 提前致谢

【问题讨论】:

好的,我会试试我的最大值 @Md Mahfuzur Ra​​hman.. 非常感谢 可悲的是,现在的亮点只是代码中的一些**;o/ @Jakumi,现在我要如何强调它 我提出了修改建议。 (<pre><code>...<b>...</b>...</code></pre> 而不是缩进 4 个空格。 【参考方案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_num 可能由于GROUP BY 而无效并被忽略。

LEFT JOIN 之后的派生表中似乎不需要 s。

为什么要分别计算BETWEEN 120 AND 180BETWEEN 180 AND 240?好像它们可以合并在一起。

如果不是更快,那么在 cmets 中进行我建议的清理工作,然后重新开始。请为每张桌子提供SHOW CREATE TABLE

【讨论】:

我接受了您的建议..非常感谢您的回复,这也是我之前比较的相同响应时间..我将从头开始

以上是关于条件检查之间的Mysql中有多个条件?有没有办法优化这个查询?的主要内容,如果未能解决你的问题,请参考以下文章

mysql在on语句中检查多个列

React 多条件检查(JSX)

缓慢的 MySQL 查询:有没有办法避免对左连接的每一行进行条件选择计数?

当其中一个在s-s-rS中有条件地不可见时如何隐藏文本框之间的空白

oracle安装过程中先决条件检查失败的解决办法

有没有办法在反应原生 iOS 中有条件地禁用滑动返回手势?