【问题标题】:Multi SELECT query for multiple ids多个 id 的多 SELECT 查询
【发布时间】:2021-04-23 06:05:32
【问题描述】:

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

【问题讨论】:

标签: mysql sql mariadb mariadb-10.3


【解决方案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

【讨论】:

    【解决方案2】:

    我建议您尝试在 2 SELECTs 中进行操作,无论用户 ID 的数量如何。

    这个人会得到所有的用户ID WHERE 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 更容易。

    【讨论】:

      猜你喜欢
      • 2014-05-01
      • 2013-03-19
      • 1970-01-01
      • 2016-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      相关资源
      最近更新 更多