Mysql 检查多个表中的值的SQL性能查询

Mysql 检查多个表中的值的SQL性能查询,mysql,sql,database-performance,Mysql,Sql,Database Performance,我正在使用MySQL 我有三张桌子: accounts { account_id, username } account_ips { idaccount_ips, account_id, ip } account_bans { ban_id account_id, expires } 需要获取每个ip中不在bans表中的帐户的分组计数。(见下文查询) 我尝试了以下方法,但速度太慢(44秒): 解释以下输出: 1, 'PRIMA

我正在使用MySQL

我有三张桌子:

accounts {
    account_id,
    username
}

account_ips {
    idaccount_ips,
    account_id,
    ip
}

account_bans {
    ban_id
    account_id,
    expires
}
需要获取每个ip中不在bans表中的帐户的分组计数。(见下文查询)

我尝试了以下方法,但速度太慢(44秒):

解释以下输出:

1, 'PRIMARY', 'a', 'ALL', '', '', '', '', 304745, 'Using where; Using temporary; Using filesort'
2, 'DEPENDENT SUBQUERY', 'b', 'ALL', '', '', '', '', 1851, 'Using where'

你需要这样做-

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.ExestRe>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
选择AIP.IP,计数(AIP.ACCOUNT\u ID)
来自帐户\u IPS AIP
左连接AIP上的帐户A。帐户\u ID=A.ACCOUNT\u ID
左加入帐户禁止A.ACCOUNT\u ID=AB.ACCOUNT\u ID上的AB
哪里
AB.BAN_ID为空

或者AB.EXPIRES尝试
左连接
并在右表中获取IP的空值,而不是
不存在的地方

FROM account_ips a
LEFT JOIN account_bans b ON b.account_id = a.account_id
WHERE b.account_id IS NULL 

此查询的运行时间几乎是我的另一个查询的8倍。
连接总是比子查询快得多
,因此,可能是因为您的子查询已被缓存,所以填充速度更快。在这种情况下,后续的运行应该会更快。让我添加一些可能有助于优化此查询的信息。account_ips中有40万条记录(并将快速增长),account_bans中只有2000条记录。我需要在5s内执行此查询=[这是一个不切实际的期望吗?我应该对索引做些什么来加快查找速度吗?你需要对帐户ID进行索引。这会有帮助的。不过,我第一次设置的索引是错误的。你的解决方案很有效。非常感谢你的建议!回答者可能会发现这个小把戏很有用:比较OP查询的执行计划和你的own(完全自由裁量权-sqlfiddle.com是我的网站)谢谢。我不知道有一个sqlfiddle。你的表上有索引吗?你能为你的查询发布
解释
输出吗?
FROM account_ips a
LEFT JOIN account_bans b ON b.account_id = a.account_id
WHERE b.account_id IS NULL