Multi SELECT 查询多个id
Multi SELECT query for multiple ids
我执行 SELECT 来决定是否向用户发送通知。 (10.3.23-MariaDB)
第一部分检查是否有 0 个未读通知,如果为 0,则不再需要 SELECT。
如果不是,我会计算自上次相同通知以来用户有多少通知(在这种情况下总是有一个可以计算)并检查未读通知数量 user_sess.unread_noti
SELECT 'yes' AS do_insert
FROM
(SELECT unread_noti
FROM user_sess
WHERE user_id = 100)user_sess
WHERE user_sess.unread_noti = 0
OR (SELECT COUNT(*) FROM notification
WHERE user_id=100 AND id > 400
) >= user_sess.unread_noti
现在我想检查多个用户的相同通知,并通过对多个用户执行 SELECT 来提高效率,例如像这个(不正确的例子):
SELECT user_sess.user_id
FROM user_sess
LEFT JOIN notification ON user_sess.unread_noti > 0
AND notification.id > 400
AND notification.user_id=user_sess.user_id
WHERE user_sess.user_id IN (100,101)
AND ( user_sess.unread_noti = 0
OR COUNT(notification.id) >= user_sess.unread_noti
)
要计数的 notification.id 对于多个用户来说可以是相同的,因为我 INSERT 它们是批量的,因此它们将占据相同的“位置”。
notification:
id Primary int(11)
user_id Index int(11)
user_sess:
user_id Primary int(11)
unread_noti tinyint(3)
我建议你尝试在 2 SELECTs
内完成,而不考虑用户 ID 的数量。
那个人会得到所有的用户 ID WHERE unread_noti = 0
。
其他人会得到那些 unread_noti != 0 AND ...
我假设 table 正在被其他线程修改?所以,使用事务:
BEGIN;
SELECT ... WHERE unread_noti = 0 FOR UPDATE;
SELECT ... WHERE unread_noti != 0 AND ... FOR UPDATE;
...
INSERT ...
COMMIT;
为什么?
OR
没有优化好
FOR UPDATE
可以解决任何并发问题
- 单独考虑每个
SELECT
更容易。
您可以使用 group by
和 having
如下:
SELECT u.user_id, 'yes' AS do_insert
FROM user_sess u
LEFT JOIN notification N ON u.user_id = n.user_id AND n.id > 400
Where u.user_id in (100, 101)
Group by u.user_id, u.unread_noti
Having max(u.unread_noti) = 0 OR count(N.USER_ID) > u.unread_noti
我执行 SELECT 来决定是否向用户发送通知。 (10.3.23-MariaDB)
第一部分检查是否有 0 个未读通知,如果为 0,则不再需要 SELECT。
如果不是,我会计算自上次相同通知以来用户有多少通知(在这种情况下总是有一个可以计算)并检查未读通知数量 user_sess.unread_noti
SELECT 'yes' AS do_insert
FROM
(SELECT unread_noti
FROM user_sess
WHERE user_id = 100)user_sess
WHERE user_sess.unread_noti = 0
OR (SELECT COUNT(*) FROM notification
WHERE user_id=100 AND id > 400
) >= user_sess.unread_noti
现在我想检查多个用户的相同通知,并通过对多个用户执行 SELECT 来提高效率,例如像这个(不正确的例子):
SELECT user_sess.user_id
FROM user_sess
LEFT JOIN notification ON user_sess.unread_noti > 0
AND notification.id > 400
AND notification.user_id=user_sess.user_id
WHERE user_sess.user_id IN (100,101)
AND ( user_sess.unread_noti = 0
OR COUNT(notification.id) >= user_sess.unread_noti
)
要计数的 notification.id 对于多个用户来说可以是相同的,因为我 INSERT 它们是批量的,因此它们将占据相同的“位置”。
notification:
id Primary int(11)
user_id Index int(11)
user_sess:
user_id Primary int(11)
unread_noti tinyint(3)
我建议你尝试在 2 SELECTs
内完成,而不考虑用户 ID 的数量。
那个人会得到所有的用户 ID WHERE unread_noti = 0
。
其他人会得到那些 unread_noti != 0 AND ...
我假设 table 正在被其他线程修改?所以,使用事务:
BEGIN;
SELECT ... WHERE unread_noti = 0 FOR UPDATE;
SELECT ... WHERE unread_noti != 0 AND ... FOR UPDATE;
...
INSERT ...
COMMIT;
为什么?
OR
没有优化好FOR UPDATE
可以解决任何并发问题- 单独考虑每个
SELECT
更容易。
您可以使用 group by
和 having
如下:
SELECT u.user_id, 'yes' AS do_insert
FROM user_sess u
LEFT JOIN notification N ON u.user_id = n.user_id AND n.id > 400
Where u.user_id in (100, 101)
Group by u.user_id, u.unread_noti
Having max(u.unread_noti) = 0 OR count(N.USER_ID) > u.unread_noti