MySQL 慢子查询,我应该使用 JOIN 吗?
MySQL slow subquery, should I use JOIN?
我正在跟踪网站上发生的用户事件(登录、注销、页面加载等)。
我想 运行 一个查询,让用户:
- 已登录
- 还没有登出
- 90 多分钟前未登录
在下面的示例中,我创建了一些数据,这些数据应该 return 只是一个 user_id = 3
的登录用户,因为
user_id 1
已注销
user_id 2
超时
user_id 3
已登录且未超时或手动退出
假设现在时间是2021-02-2412:15:00
id
user_id
description
created_at
19954
3
log in
2021-02-24 12:00:00
16085
1
log out
2021-02-24 12:00:00
11844
2
log in
2021-02-24 10:00:00
16850
1
log in
2021-02-24 10:00:00
我当前的查询是这样的,但是 运行 真的很慢。
SELECT DISTINCT(user_id), id, created_at
FROM events e1
WHERE id = (
SELECT id
FROM events e2
WHERE e2.user_id = e1.user_id
AND description IN ('log in', 'log out')
ORDER BY created_at desc
LIMIT 1
)
AND description = 'log in'
AND created_at > NOW() - INTERVAL 90 MINUTE
ORDER BY created_at desc
我的指标如下
PRIMARY
BTREE
TRUE
id
description_index
BTREE
FALSE
description
user_desc_created_index
BTREE
FALSE
user_id,description,created_at
user_id_description_index
BTREE
FALSE
user_id,description
我想我可能需要一个连接而不是子查询,但我不确定具体怎么做。谁能伸出援手?
您可以尝试将 joi 与 subqiery 一起用于 user_id
的最大日期组
SELECT DISTINCT user_id , id, created_at
FROM events e1
INNER JOIN (
select user_id, max(created_at) max_date
from events
WHERE description IN ('log in', 'log out')
group by user_id
) t1
inner join events t2 ON t1.user_id = t2.user_id and t1.max_date = t2.created_at
WHERE t2-description = 'log in'
AND t2.created_at > NOW() - INTERVAL 90 MINUTE
ORDER BY t2.created_at desc
我正在跟踪网站上发生的用户事件(登录、注销、页面加载等)。
我想 运行 一个查询,让用户:
- 已登录
- 还没有登出
- 90 多分钟前未登录
在下面的示例中,我创建了一些数据,这些数据应该 return 只是一个 user_id = 3
的登录用户,因为
user_id 1
已注销user_id 2
超时user_id 3
已登录且未超时或手动退出
假设现在时间是2021-02-2412:15:00
id | user_id | description | created_at |
---|---|---|---|
19954 | 3 | log in | 2021-02-24 12:00:00 |
16085 | 1 | log out | 2021-02-24 12:00:00 |
11844 | 2 | log in | 2021-02-24 10:00:00 |
16850 | 1 | log in | 2021-02-24 10:00:00 |
我当前的查询是这样的,但是 运行 真的很慢。
SELECT DISTINCT(user_id), id, created_at
FROM events e1
WHERE id = (
SELECT id
FROM events e2
WHERE e2.user_id = e1.user_id
AND description IN ('log in', 'log out')
ORDER BY created_at desc
LIMIT 1
)
AND description = 'log in'
AND created_at > NOW() - INTERVAL 90 MINUTE
ORDER BY created_at desc
我的指标如下
PRIMARY | BTREE | TRUE | id |
description_index | BTREE | FALSE | description |
user_desc_created_index | BTREE | FALSE | user_id,description,created_at |
user_id_description_index | BTREE | FALSE | user_id,description |
我想我可能需要一个连接而不是子查询,但我不确定具体怎么做。谁能伸出援手?
您可以尝试将 joi 与 subqiery 一起用于 user_id
的最大日期组SELECT DISTINCT user_id , id, created_at
FROM events e1
INNER JOIN (
select user_id, max(created_at) max_date
from events
WHERE description IN ('log in', 'log out')
group by user_id
) t1
inner join events t2 ON t1.user_id = t2.user_id and t1.max_date = t2.created_at
WHERE t2-description = 'log in'
AND t2.created_at > NOW() - INTERVAL 90 MINUTE
ORDER BY t2.created_at desc