9行的myqsl持续时间,这就是我的代码

时间:2019-06-21 16:08:55

标签: mysql

SELECT DATE_FORMAT(b.checktime,"%Y-%m-%d") AS dtDate,
   case when (
   SELECT DATE_FORMAT(a.checktime,'%H:%i:%s')
   FROM checkinout a 
   WHERE a.checktype='0'
   and a.userid=1
   and DATE_FORMAT(a.checktime,'%Y-%m-%d')=DATE_FORMAT(b.checktime,'%Y-%m-%d')
   LIMIT 1)
   is not NULL 
   then
   (
   SELECT
   DATE_FORMAT(a.checktime,'%H:%i:%s')
   FROM checkinout a 
   WHERE a.checktype='0'
   and a.userid=1
   and DATE_FORMAT(a.checktime,'%Y-%m-%d')=DATE_FORMAT(b.checktime,'%Y-%m-%d')
  LIMIT 1
  ) 
  else 'N/A' END
  AS Chkin
  from checkinout b
  where
  DATE_FORMAT(b.checktime,"%m")='06' AND
  DATE_FORMAT(b.checktime,"%Y")='2019' AND
  DATE_FORMAT(b.checktime,"%w")!='0' AND . 
  DATE_FORMAT(b.checktime,"%w")!='6' AND .  
  DATE_FORMAT(b.checktime,"%Y-%m-%d") not in 
  (select date_s from wend)
  GROUP BY dtDate 
  ORDER BY dtDate DESC
  

受影响的行:0找到的行:9警告:0 1个查询的持续时间:25.665秒。

此查询出了什么问题,因为9行需要25.665秒

谢谢

1 个答案:

答案 0 :(得分:0)

在不了解查询目的的情况下,可以将其重写为:

SELECT DISTINCT date(b.checktime) AS dtDate,
    coalesce((
        SELECT time(a.checktime)
        FROM checkinout a
        WHERE a.checktype = '0'
          and a.userid = 1
          and date(a.checktime) = date(b.checktime)
        LIMIT 1
    ), 'N/A') AS Chkin
from checkinout b
where month(b.checktime) = 6
  AND year(b.checktime) = 2019
  AND weekday(b.checktime) not in (5, 6) -- non weekend
  AND date(b.checktime) not in (select date_s from wend)
ORDER BY dtDate DESC

尽管GROUP BY的性能可能优于DISTINCT-您应该同时测试两者。但是,可以优化上述查询以使用索引。

外部条件month(b.checktime) = 6 AND year(b.checktime) = 2019可以重写为b.checktime >= '2019-06-01' AND b.checktime < '2019-06-01' + INTERVAL 1 MONTH。这样,引擎就应该能够在(checktime)上使用索引。

条件date(a.checktime) = date(b.checktime)可以写为a.checktime >= date(b.checktime) and a.checktime < date(b.checktime) + INTERVAL 1 DAY。在这里,我建议使用以下索引之一:(checktype, userid, checktime)(userid, checktype, checktime)(userid, checktime)

对于date(b.checktime) not in (select date_s from wend),最好使用“反连接”。

这是我要尝试的最终查询:

SELECT DISTINCT date(b.checktime) AS dtDate,
    coalesce((
        SELECT time(a.checktime)
        FROM checkinout a
        WHERE a.checktype = '0'
          and a.userid = 1
          and a.checktime >= date(b.checktime)
          and a.checktime <  date(b.checktime) + INTERVAL 1 DAY
        LIMIT 1
    ), 'N/A') AS Chkin
from checkinout b
LEFT JOIN wend w ON w.date_s = date(b.checktime)
where b.checktime >= '2019-06-01'
  AND b.checktime <  '2019-06-01' + INTERVAL 1 MONTH
  AND weekday(b.checktime) not in (5, 6) -- non weekend
  AND w.date_s IS NULL
ORDER BY dtDate DESC