1TB量级数据入Synapse SQL:增量加载初始水印与日期范围问题
Synapse SQL增量加载解决方案
一、水印表初始时间戳设置
- 若首次全量加载前配置水印表:直接设置为源数据中最早的记录时间戳(比如源数据起始日期的
00:00:00),这样第一次增量加载就能覆盖所有历史数据,后续每次增量仅拉取该时间戳之后的新数据。 - 若已完成全量加载:将水印表时间戳设置为全量加载完成时的最大记录时间戳,确保后续增量只同步全量之后新增的数据,避免重复加载。
无需刻意填入源数据起始日期,核心是匹配实际加载范围——要从最开始同步全量就设最早时间,已完成全量就设全量的截止时间。
二、每月增量加载的数据范围逻辑实现
通过水印表记录的上次加载时间,结合日期函数计算当月的起始和结束范围,具体实现思路如下:
- 从水印表读取上次加载时间戳,记为
last_watermark - 计算周期起始时间:首次执行时取源数据最早时间;非首次则取
last_watermark下一个月的第一天,比如用DATEFROMPARTS(YEAR(last_watermark), MONTH(last_watermark)+1, 1) - 计算周期结束时间:取目标月份的最后一天,比如
EOMONTH(GETDATE()) - 编写SQL筛选源数据时,用
WHERE 源数据时间戳 >= 周期起始时间 AND 源数据时间戳 < 周期结束时间 - 加载完成后,更新水印表时间戳为本次周期的结束时间,确保下次加载从下一个周期开始
以下是T-SQL示例:
-- 读取上次水印 DECLARE @last_watermark DATETIME SELECT @last_watermark = MAX(watermark_time) FROM dbo.watermark_table -- 计算周期范围 DECLARE @start_time DATETIME, @end_time DATETIME IF @last_watermark IS NULL -- 首次执行 BEGIN SELECT @start_time = MIN(created_time) FROM source_table SELECT @end_time = EOMONTH(@start_time) END ELSE BEGIN SET @start_time = DATEFROMPARTS(YEAR(@last_watermark), MONTH(@last_watermark)+1, 1) SET @end_time = EOMONTH(@start_time) END -- 加载增量数据 INSERT INTO synapse_target_table SELECT * FROM source_table WHERE created_time >= @start_time AND created_time < DATEADD(DAY, 1, @end_time) -- 避免漏选当天23:59:59的数据 -- 更新水印表 MERGE INTO dbo.watermark_table AS target USING (SELECT @end_time AS watermark_time) AS source ON 1=1 -- 单条记录的水印表 WHEN MATCHED THEN UPDATE SET target.watermark_time = source.watermark_time WHEN NOT MATCHED THEN INSERT (watermark_time) VALUES (source.watermark_time);
注意:如果源数据时间戳有毫秒级精度,要确保时间范围边界处理准确,避免重复或遗漏数据。
内容的提问来源于stack exchange,提问作者CloudEngineer
相关产品推荐
相关产品推荐

