sql - SELECT DISTINCT 非常慢

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

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

相关文章:

sql - 是否可以将元组数组中的值添加到表中的单独列中

SQL - 将单列分成多列

c++ - 在 C++ 中使用指针会减少运行时间?

sql-server - 为什么我的表值参数在到达数据库时为空?

sql - 以编程方式生成 SQL 脚本以在没有 PRIMARY 语句的情况下创建数据库..使用脚本程序

sql - 在 PostgreSQL 中查找部分匹配条件的行

mysql - 如何提高mysql查询时缓存的使用

regex - 如何优化正则表达式中的边界检查?

sql - 无法更改 SQL Server 2008 中的表设计

sql - T-SQL标签数据库架构设计?