这个(为简单起见修改)查询是更大查询的一部分,并在日期上与其他选择连接。但是,我已将这一部分固定为慢狗。假设我有一个 UserLoginHistory 表,用于记录用户的每次登录。对于每个用户,我想要他们首次登录的日期。(稍后在查询中,我按 LogDate 分组以获取每天有多少首次登录。)
select
LogDate, --(this value is only date, no time)
UserId
from
UserLoginHistory ul
where
not exists
(
select
*
from
UserLoginHistory ulPrevious
where
ulPrevious.LogDate < ul.LogDate
and ul.UserId = ulPrevious.UserId
)
group by ul.LogDate, ul.UserId
显然 NOT EXISTS 部分是慢的。但我不知道如何用做同样工作的更有效的东西来代替它。
使用小的 UserLogHistory-count,性能没有问题。当我达到 15 000 左右时,它开始变慢。也许我应该将每天的结果批处理到另一个表中,但我想为这个查询找到一个更好的解决方案,因为应该有一个......
谢谢你的时间!
最佳答案
您可以使用行编号方法:
select LogDate,UserId from (
select
LogDate,
UserId
row_number() over (partition by UserId order by LogDate) as rown
from
UserLoginHistory ul
)
where rown = 1
每个 ID 的行按 LogDate 编号,因此最早的行将始终编号为 1。
注意:我不认为原始查询中的
group by
是必要的——not exists
子句应该保证你只获得 UserId 和 LogDate 的唯一组合。关于sql - NOT EXISTS 的性能 - t-sql 查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15275564/