2

我有一个查询需要 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

有没有更好的方法来做到这一点?

4

1 回答 1

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

如果我的猜测是真的,那么这肯定会运行得更快。

于 2012-05-29T23:46:44.550 回答