我的查询执行时间为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条
有更好的方法吗?
答案 0 :(得分:4)
您遇到的问题是执行计划。我的猜测是“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
如果我的猜测是真的,那么这肯定会跑得更快。