多个id的Multi SELECT查询



我执行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
) 

的通知。对于多个用户来说,id可以是相同的,因为我批量插入它们,所以它们将占用相同的"位置"。

notification:
id        Primary   int(11) 
user_id   Index     int(11) 
user_sess:
user_id     Primary int(11)
unread_noti         tinyint(3)

我建议您尝试在2SELECTs中这样做,而不管userid的数量。

一个将获得所有用户idWHERE unread_noti = 0

另一个是含有unread_noti != 0 AND ...

的我假设有一个问题,表正在被其他线程修改?因此,使用事务:

BEGIN;
SELECT ... WHERE unread_noti = 0          FOR UPDATE;
SELECT ... WHERE unread_noti != 0 AND ... FOR UPDATE;
...
INSERT ...
COMMIT;

为什么?

  • OR优化效果不佳
  • FOR UPDATE可以解决任何并发问题
  • 单独考虑每个SELECT更容易。

可以这样使用group byhaving:

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