显示SQL中每个用户的最新值(快速)

时间:2018-09-06 14:45:28

标签: mysql sql select group-by

我正在尝试查找用户在过去24小时内的最后行动是否进出(这是一种用于在紧急情况下知道哪些人还在建筑物中的软件)。该表大约有200万行,我们有3000个用户。

我找到的唯一解决方案是以下解决方案,它可以工作,但问题是需要15秒...

SELECT TIME, firstname, lastname, dept
FROM DAY
WHERE event_point_id IN (20, 22, 24, 26, 28, 30)
  AND id IN (SELECT MAX(id)
             FROM DAY
             GROUP BY pin)
GROUP BY pin
ORDER BY TIME ASC

DAY是具有以下详细信息的视图

SELECT id, pin, event_point_id, time, firstname, lastname, dept
FROM acc_monitor_log
WHERE (((TO_DAYS(NOW()) - TO_DAYS(time)) < 1) AND (pin <> '--'))

有什么方法可以加快速度?

3 个答案:

答案 0 :(得分:1)

如果我理解正确,那么您的DAY视图已经在过滤过去24小时内的条目,而您想要的是从该视图中仅获取每个用户的最新行。

如果是的话,像这样简单的事情应该可以解决问题,并且比我认为IN更快。

SELECT MAX(TIME), pin, firstname, lastname, dept
FROM DAY
WHERE event_point_id IN (20, 22, 24, 26, 28, 30)
GROUP BY pin, firstname, lastname, dept
ORDER BY TIME ASC

答案 1 :(得分:0)

第一个建议是使用内部联接来减少IN子句

SELECT TIME,firstname,lastname,dept
  FROM DAY
  INNER JOIN (
    SELECT pin, MAX(id) max_id 
    FROM DAY
    GROUP BY pin)
  ) T on t.max_id = DAY.id and t.pin = day.pin
  WHERE event_point_id IN (20,22,24,26,28,30)
  ORDER BY TIME ASC

SELECT TIME,firstname,lastname,dept
  FROM DAY
  INNER JOIN (
    SELECT pin, MAX(id) max_id 
    FROM DAY
    GROUP BY pin)
  ) T on t.max_id = DAY.id and t.pin = day.pin
  INNER JOIN (
    select 20 as my_point from dual
    union 
    select 22 from dual
     union 
    select 24 from dual       
    union 
    select 26 from dual
    union 
    select 28 from dual  
    union 
    select 30 from dual      
  ) t2  on t2.my_point  = DAY.event_point
  ORDER BY TIME ASC

,并确保在列(引脚,ID)上具有正确的索引..并且您也可以尝试使用索引而不是IN子句或子查询为值20 .... 30添加适当的表,并在这张表

答案 2 :(得分:0)

首先,我将使用相关子查询并摆脱GROUP BY

SELECT d.TIME, d.firstname, d.lastname, d.dept
FROM DAY d
WHERE d.event_point_id IN (20, 22, 24, 26, 28, 30) AND
      d.id = (SELECT MAX(d2.id)
              FROM Day d2
              WHERE d2.pin = d.pin
             )
ORDER BY TIME ASC;

然后,请确保您在基础表acc_monitor_log(pin, id)acc_monitor_log(event_point_id, pin, id)上都有索引。