我正在使用MySQL
我有三张桌子:
accounts {
account_id,
username
}
account_ips {
idaccount_ips,
account_id,
ip
}
account_bans {
ban_id
account_id,
expires
}
需要获得不在禁止表中的每个ip的帐户的分组计数。 (见下面的查询)
我尝试了以下内容,但速度太慢(44秒):
SELECT DISTINCT a.account_id, count(DISTINCT a.account_id)
FROM account_ips AS a
WHERE NOT EXISTS(
SELECT 1
FROM account_bans AS b
WHERE b.expires > 1340341272 AND b.account_id = a.account_id)
GROUP BY a.ip
HAVING count(DISTINCT a.account_id) > 3
ORDER BY count(DISTINCT a.account_id) DESC;
解释输出如下:
1, 'PRIMARY', 'a', 'ALL', '', '', '', '', 304745, 'Using where; Using temporary; Using filesort'
2, 'DEPENDENT SUBQUERY', 'b', 'ALL', '', '', '', '', 1851, 'Using where'
答案 0 :(得分:2)
你需要这样做 -
SELECT AIP.IP, COUNT(AIP.ACCOUNT_ID)
FROM ACCOUNT_IPS AIP
LEFT JOIN ACCOUNTS A ON AIP.ACCOUNT_ID=A.ACCOUNT_ID
LEFT JOIN ACCOUNT_BANS AB ON A.ACCOUNT_ID=AB.ACCOUNT_ID
WHERE
AB.BAN_ID IS NULL
GROUP BY AIP.IP
如果您还需要考虑b.expires> 1340341272然后查询将是 -
SELECT AIP.IP, COUNT(AIP.ACCOUNT_ID)
FROM ACCOUNT_IPS AIP
LEFT JOIN ACCOUNTS A ON AIP.ACCOUNT_ID=A.ACCOUNT_ID
LEFT JOIN ACCOUNT_BANS AB ON A.ACCOUNT_ID=AB.ACCOUNT_ID
WHERE
AB.BAN_ID IS NULL
OR AB.EXPIRES <= 1340341272
GROUP BY AIP.IP
答案 1 :(得分:0)
尝试left join
并在右表中获取ips的空值,而不是WHERE NOT EXISTS
。
FROM account_ips a
LEFT JOIN account_bans b ON b.account_id = a.account_id
WHERE b.account_id IS NULL