我有一个查询需要 48 秒才能执行,如下所示:
SELECT count(DISTINCT tmd_logins.userID) as totalLoginsUniqueLast30Days
FROM tmd_logins
join tmd_users on tmd_logins.userID = tmd_users.userID
where tmd_users.isPatient = 1 AND loggedIn > '2011-03-25'
and tmd_logins.userID in
(SELECT userID as accounts30Days FROM tmd_users
where isPatient = 1 AND created > '2012-04-29' AND computerID is null)
当我删除 DISTINCT
关键字时,花费的时间不到 1 秒,因此看来瓶颈就在其中。
每次用户登录系统时,数据库都会向 tmd_logins
表添加一个条目。我正在尝试获取在给定时间段(例如过去 30 天内)内创建并登录的所有用户的总数。
我已尝试删除 DISTINCT 关键字并将 group by tmd_logins.userID
添加到语句中,但性能问题仍然存在。
表tmd_logins
有大约300,000条记录,tmd_users
有大约40,000条
有更好的方法吗?
最佳答案
您遇到的问题是执行计划。我的猜测是“in”子句可能会混淆它。您可以尝试:
SELECT count(DISTINCT tmd_logins.userID) as totalLoginsUniqueLast30Days
FROM tmd_logins join
tmd_users
on tmd_logins.userID = tmd_users.userID join
(SELECT distinct userID as accounts30Days
FROM tmd_users
where isPatient = 1 AND
created > '2012-04-29' AND
computerID is null
) t
on tmd_logins.userID = t.accounts30Days
where tmd_users.isPatient = 1 AND
loggedIn > '2011-03-25'
这可能有效,也可能无效。但是,我想知道查询本身的结构。看起来 UserID 在名为 tmd_users 的表中应该是不同的。如果是这样,那么您可以将所有条件合并为一个:
SELECT count(DISTINCT tmd_logins.userID) as totalLoginsUniqueLast30Days
FROM tmd_logins join
tmd_users
on tmd_logins.userID = tmd_users.userID
where tmd_users.isPatient = 1 AND
loggedIn > '2011-03-25' and
created > '2012-04-29' AND
computerID is null
如果我的猜测是正确的,那么这肯定会运行得更快。
关于sql - SELECT DISTINCT 非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10808110/