将子查询结果设置为数组,运行时间太长

时间:2014-09-30 20:28:30

标签: mysql sql

我正在处理一个运行速度非常慢的查询,并试图找出如何将子查询加载到数组或其他东西以使其更快。

SELECT COUNT(bdgid)
FROM member_badges
WHERE usid in(
    SELECT usid
    FROM member_badges
    WHERE bdgid in (1,4,5,6,7,8)
    GROUP BY usid
    HAVING COUNT(usid) =6)
GROUP BY bdgid

子查询返回usid的特定集合列表,主查询计算包含其中一个用户ID的bdgid。但是这个例子运行时间太长了。

mbrbdid    usid      bdgid
------------------------------
1            14        1
2            11        4
3            25        4
4            11        7
5            11        8
6            22        1

该表有超过30,0000条记录。基本上,usid每次可以获得1-10个徽章。此表是每次用户获取徽章时的实例。 因此,我试图让所有拥有徽章的人(1,4,5,6,7,8),然后计算每个徽章的数量1-10,但只使用那些特定的身份证。

3 个答案:

答案 0 :(得分:2)

您的子查询正在运行外部查询中的每一行,您可以通过使用子查询结果作为子选择的连接来重写查询。这样,子选择将被评估一次,结果将与外部查询连接,usid和bdgid的索引也很有帮助

SELECT COUNT(bdgid)
FROM member_badges a
join (
    SELECT usid
    FROM member_badges
    WHERE bdgid in (1,4,5,6,7,8)
    GROUP BY usid
    HAVING COUNT(usid) =6) b
on(a.usid = b.usid)
GROUP BY bdgid

答案 1 :(得分:1)

使用临时表拆分查询并加入临时表...

create temporary table usid_temp SELECT usid
FROM member_badges
WHERE bdgid in (1,4,5,6,7,8)
GROUP BY usid
HAVING COUNT(usid) =6

- 然后加入

SELECT COUNT(bdgid)
FROM member_badges a, usid_temp b
where a.usid = b.usid group by bdgid

当我发布这个时,我实际上赞成了Khalids的回答,因为他是一个更好的答案。

答案 2 :(得分:0)

在这种情况下,我建议使用EXISTS代替IN

SELECT COUNT(bdgid)
FROM member_badges A
WHERE EXISTS (
    SELECT B.usid
    FROM member_badges B
    WHERE B.bdgid in (1,4,5,6,7,8)
    and A.UsID=B.usID
    GROUP BY B.usid
    HAVING COUNT(B.usid) =6)
GROUP BY bdgid