0

我执行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 对于多个用户可以是相同的,因为我批量插入它们,所以它们将占据相同的“位置”。

notification:
id        Primary   int(11) 
user_id   Index     int(11) 

user_sess:
user_id     Primary int(11)
unread_noti         tinyint(3)
4

2 回答 2

1

I suggest you try to do it in 2 SELECTs, regardless of the number of userids.

The one would get all the userids WHERE unread_noti = 0.

The other would get those that have unread_noti != 0 AND ...

I assume there is an issue that the table is being modified by other threads? So, use a transaction:

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

Why?

  • OR does not optimize well
  • FOR UPDATE may solve any concurrency issues
  • It is easier to think through each SELECT separately.
于 2021-01-18T23:05:26.837 回答
1

您可以使用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
于 2021-01-19T02:02:24.943 回答