【问题标题】:SELECT DISTINCT Extremely slowSELECT DISTINCT 极慢
【发布时间】:2012-05-29 23:28:04
【问题描述】:

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

有更好的方法吗?

【问题讨论】:

  • 一个愚蠢的问题:您是否尝试改用DISTINCT tmd_users.userID?结果应该是一样的,但是使用优化器可能会更好,因为 tmd_users.userID 已编入索引(当然,假设它的主键为 tmd_users)。
  • 你有关于 created 和 loggedIn 的索引吗?
  • 我们可以看看执行计划吗?
  • Gordon 的第二个解决方案效果很好。我又玩了一会儿,发现如果我取出第一个 where tmd_users.isPatient 子句,它也会修复它。谢谢!

标签: sql performance sql-server-2008 distinct sql-optimization


【解决方案1】:

您遇到的问题是执行计划。我的猜测是“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

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

【讨论】:

    猜你喜欢
    • 2021-07-06
    • 1970-01-01
    • 2023-03-15
    • 2012-10-13
    • 2016-01-26
    • 2017-01-25
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多