子查询的JOIN替代方案

时间:2017-05-27 14:04:33

标签: mysql database join

我正在尝试向登录用户显示他们每次登录时尚未看到的通知数。为此,我有以下查询:

"select count(eventId) as count from notifications where updateId in("
 # 2-the updates NOT IN what the user has seen
 "select updateId from updates where updateId not in("
 # 1-the updates the user has seen
 "select updateId from seen_updates where memberId={}))".format(memberId))

问题是,随着通知数量的增加,这似乎需要一段时间。有没有办法通过加入更好地做到这一点?


mysql> describe notifications;
+----------+------------------+------+-----+---------+-------+
| Field    | Type             | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+-------+
| eventId  | int(10) unsigned | NO   |     | NULL    |       |
| updateId | int(10) unsigned | YES  |     | NULL    |       |
+----------+------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> describe updates;
+---------------+------------------+------+-----+-------------------+----------------+
| Field         | Type             | Null | Key | Default           | Extra          |
+---------------+------------------+------+-----+-------------------+----------------+
| updated       | timestamp        | NO   |     | CURRENT_TIMESTAMP |                |
| updateId      | int(10) unsigned | NO   | PRI | NULL              | auto_increment |
| eventCategory | varchar(40)      | YES  |     | NULL              |                |
| eventsCount   | int(10) unsigned | NO   |     | NULL              |                |
+---------------+------------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)

mysql> describe seen_updates;
+----------+------------------+------+-----+-------------------+-------+
| Field    | Type             | Null | Key | Default           | Extra |
+----------+------------------+------+-----+-------------------+-------+
| updateId | int(10) unsigned | NO   |     | NULL              |       |
| memberId | int(10) unsigned | NO   |     | NULL              |       |
| updated  | timestamp        | NO   |     | CURRENT_TIMESTAMP |       |
+----------+------------

2 个答案:

答案 0 :(得分:2)

使用连接,你可以这样做:

select     count(eventId) as count 
from       notifications 
inner join updates 
        on updates.updateId = notifications.updateId
left join  seen_updates 
        on seen_updates.updateId = notifications.updateId
       and seen_updates.memberId = {}
where      seen_updates.updateId is null

根据您的数据结构,您甚至可能不需要inner join updates的子句。似乎合乎逻辑的是notification.updateId需要在updates表中具有现有的对应物。只有在无法保证inner join需要保留的情况下才能保留。

答案 1 :(得分:0)

无需更改查询以加入连接并承担风险,因为根据架构详细信息,以下两个索引首先是主要的丢失对象,这会导致速度缓慢

  1. 表“ Notification”的“ update_Id”列上的索引

  2. 表“ Seen_Updates”的“ member_id”列上的索引