创建SSIS作业清理180天未使用SSRS报表用户及SQL查询咨询
SSRS用户清理查询的问题分析与优化方案
原查询的核心问题
- 逻辑错误:如果用户同时存在180天前的旧执行记录和最近180天内的活跃记录,原查询会因为旧记录的存在将这个活跃用户误筛选出来——这完全违背了“清理180天未使用报表用户”的初衷。
- 性能隐患:
LEFT JOIN搭配DISTINCT的组合,在数据量大时会产生大量中间关联数据,再去重会显著拖慢查询速度。
正确的实现逻辑及优化写法
我们真正要找的是过去180天内没有任何报表执行行为的用户,包含两类:从未使用过报表的用户,以及最后一次使用在180天前的用户。
方案一:用NOT EXISTS(性能最优,逻辑最清晰)
SELECT u.UserName FROM dbo.Users u WHERE NOT EXISTS ( SELECT 1 FROM dbo.ExecutionLog l WHERE u.UserName = l.UserName AND l.TimeStart > DATEADD(DAY, -180, GETDATE()) )
这个写法直接排除掉所有180天内有执行记录的用户,剩下的就是符合清理条件的用户。不需要DISTINCT,执行计划更高效,逻辑也一目了然。
方案二:聚合最后执行时间(适合需要排查历史的场景)
如果需要同时查看用户最后一次使用报表的时间,可以先对执行日志做分组聚合:
SELECT u.UserName FROM dbo.Users u LEFT JOIN ( SELECT UserName, MAX(TimeStart) AS LastExecutionTime FROM dbo.ExecutionLog GROUP BY UserName ) l ON u.UserName = l.UserName WHERE l.LastExecutionTime <= DATEADD(DAY, -180, GETDATE()) OR l.LastExecutionTime IS NULL
先算出每个用户的最后执行时间,再和用户表关联,彻底避免了原查询中“误判活跃用户”的问题,还能直观看到用户的最后使用时间,方便后续验证。
额外提醒
- 确认
ExecutionLog.TimeStart的时区是否和业务逻辑匹配,如果服务器时区与用户使用时区不一致,需要调整日期计算的偏移量。 - 一定要先在测试环境验证查询结果,确认没有误筛活跃用户后,再整合到SSIS作业中。
- 若两张表数据量较大,给
ExecutionLog建立(UserName, TimeStart)联合索引,能大幅提升查询速度。
内容的提问来源于stack exchange,提问作者amikm
相关产品推荐
相关产品推荐

