我需要更快的SQL查询来查找过期的订阅者

时间:2012-04-10 10:51:12

标签: mysql join

我在MySQL成员和订阅者中有2个表。我想做的是;我想找到至少有1个过期订阅且没有有效订阅的订阅者。

SELECT mem.id as id 

FROM members as mem 
INNER JOIN subscriptions as sub ON sub.member_id = mem.id 

WHERE 
sub.active = 0 AND 
NOT EXISTS ( SELECT 1 FROM subscriptions as sub2 WHERE sub2.member_id = mem.id AND sub2.active = 1 )

Group By mem.id

此查询处理时间过长(考虑到2个表保存的记录数量,这是正常的)。

我等了大约2分钟才看到结果,但由于它还在尝试加载,我刚刚取消了它。我需要更快的结果。有没有其他方法可以做到这一点?

感谢您的时间和关注。

3 个答案:

答案 0 :(得分:1)

我猜不出为什么你这样做你的sql但这可能有效

SELECT mem.id as id 
FROM members as mem 
INNER JOIN subscriptions as sub ON sub.member_id = mem.id 
WHERE sub.active = 0 
Group By mem.id

更新:我想您可能会添加deactivted_date列或其他内容来指示过期

答案 1 :(得分:1)

你走了。 (确保你有适当的索引)。另请注意,我离开了原始联接,因为我假设您在某些时候想要的不仅仅是member_id。但如果你想要的只是member_id,你可以一起删除成员表。

/*
insert members (member_name) values ('tom')
insert members (member_name) values ('bob')
insert members (member_name) values ('jim')

declare @tom int
set @tom = (select member_id from members where member_name = 'tom')

insert subscriptions (member_id, is_active) values (@tom, 1)
insert subscriptions (member_id, is_active) values (@tom, 0)

declare @bob int
set @bob = (select member_id from members where member_name = 'bob')

insert subscriptions (member_id, is_active) values (@bob, 0)
insert subscriptions (member_id, is_active) values (@bob, 0)
*/

SELECT m.member_id
FROM members as m 
INNER JOIN subscriptions as s ON s.member_id = m.member_id 
LEFT JOIN subscriptions s2 on s2.member_id = m.member_id and s2.is_active = 1
WHERE 
s.is_active = 0 and
s2.subscription_id is null

Group By m.member_id

OR

SELECT s.member_id
FROM subscriptions as s
LEFT JOIN subscriptions s2 on s2.member_id = s.member_id and s2.is_active = 1
WHERE 
s.is_active = 0 and
s2.subscription_id is null

Group By s.member_id

答案 2 :(得分:0)

DISTINCT和group by应该执行相同的操作,但我发现DISTINCT的查询更具可读性。

活跃的索引可能会加快查询速度。

SELECT DISTINCT mem.id as id
FROM members as mem, subscriptions as sub WHERE sub.member_id = mem.id AND 
sub.active = 0 AND NOT EXISTS (
   SELECT * FROM subscriptions as sub2
   WHERE sub2.member_id = mem.id AND sub2.active = 1
)