我正在尝试查找用户在过去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 <> '--'))
有什么方法可以加快速度?
答案 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)
上都有索引。