如何通过指定LogId从仅保留变更记录的历史表提取对应快照数据
问题描述
我有如下结构的表:
对应的日志表如下:
我的主表每日从源端同步数据,但仅保留发生变更的记录,正常情况下每日同步10万条记录,实际产生变更的不足100条,主表通过log ID关联日志表跟踪所有记录的变更情况。
目前我使用以下查询可以正常提取最新数据或任意指定日期的快照数据:
select * from (select pcode,description,T.logid,extractiondate,dense_rank() over(partition by pcode order by extractiondate desc) rn from @temp T inner join @logs L on L.logid=T.logid where L.extractiondate<=(select max(extractiondate) from @logs))tbl where rn=1 order by extractiondate desc

将子查询中的max(extractiondate)替换为指定日期,即可获取对应日期的全量快照数据,该逻辑运行无问题。
现在我有新的需求:不通过指定日期,而是直接指定LogId来获取对应LogId时刻的全量快照数据。我知道可以先查询该LogId对应的日期再代入原有查询实现,但我希望找到直接基于LogId实现的更优方案,请求帮助。
解决方案
日志表的logid是按生成顺序自增的,数值越大对应日志生成时间越晚,因此可以直接基于logid做过滤,无需额外查询对应日期,性能更优。
将以下查询中的@target_logid替换为你需要指定的LogId即可使用:
SELECT * FROM ( SELECT pcode, description, T.logid, extractiondate, DENSE_RANK() OVER(PARTITION BY pcode ORDER BY T.logid DESC) rn FROM @temp T INNER JOIN @logs L ON L.logid = T.logid WHERE L.logid <= @target_logid ) tbl WHERE rn = 1 ORDER BY extractiondate DESC
该方案的优势:
- 省去了查询目标LogId对应日期的步骤,减少一次查询开销
- 若
logid字段建有索引,过滤和排序的效率远高于基于日期字段的查询 - 输出结果和先查日期再代入原有查询的结果完全一致,逻辑兼容性好
内容的提问来源于stack exchange,提问作者Sandeep Thomas
相关产品推荐
相关产品推荐

