Table 的增量更新
Incremental update of Table
我正在使用 SSIS 包将数据从 SQL 服务器复制到 Oracle,我想通过增量更新提高复制性能。
我的想法是:
- 追加 table 的新记录。(在追加之前删除它们)
- 删除 "Deleted" 条记录
代码:
drop table A1
drop table A2
--Old Table
create Table A1(id int,
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
--New Table
create Table A2(id int,
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
insert into A1 (id, a1, a2, a3, a4, a5, a6, a7, a8)
values (1,1,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8),
(4,3,1,3,4,5,7,3,8)
insert into A2 (id, a1, a2, a3, a4, a5, a6, a7, a8)
values (1,2,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8)
--1) Changed values
select * from a2
except
select * from a1;
--2) "Deleted" Values. If I Have primary key in A1,A2 the result is simply get by query
select a1.*
from A1
left join A2 on a2.id = a1.id
where a2.id is null
但在我的真实情况下,我的 table 上没有主键。我如何通过另一种方式实现 2 点,而不通过主键连接?
查询结果:
id a1 a2 a3 a4 a5 a6 a7 a8
1 2 2 3 4 5 6 7 8
id a1 a2 a3 a4 a5 a6 a7 a8
4 3 1 3 4 5 7 3 8
您可以使用 CDC 或其他基于日志文件而不是查询的日志传送机制。如果您仍想将 SSIS 用于查询 -
您是否尝试过在 SQL 服务器上使用 rowversion 来查找差异,它会比 [=21= 更快]当然除外。
select * from a2 where rowversion > @lastmaxrowversion;
发现删除是一件很难的事,你能做的最好的就是
select a1.id from a1 where not exists (select top 1 1 from a2 where
a1.id = a2.id);
如果您可以添加删除触发器并将 ID 保存在 table 中,那也很好。
- 请记住,许多公司并不真正关心他们的 ETL 过程中删除的记录,因为存储不再是个问题。此外,如今您可以使用分区 table 归档或活动标志设计不删除的系统。无论如何,如果删除仍然很重要,可以尝试为 insert/update 与删除设置不同的间隔。例如,每 10 分钟检查一次 insert/update,其中每 24 小时删除一次。
通过使用 MERGE 语句,您可以在单个操作中执行 INSERT、UPDATE 和 DELETE,这是增量加载的理想选择。
示例代码:
MERGE A2 AS target
USING (SELECT * FROM A1) AS source
ON (target.Id = source.Id AND target.a1 = Source.a1...) -- More join condition
WHEN MATCHED THEN
UPDATE SET a2 = source.a2, a3 = source.a3 ------ more columns
WHEN NOT MATCHED THEN
INSERT (Id, A1, a1, a2....)
VALUES (source.Id, source.a1, source.a2.....)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
END;
MERGE 语句还提供了捕获插入、删除和更新记录的灵活性(以防万一,您需要它们进行日志记录),但在您真正需要这些信息之前我不推荐它们。
在上面的查询中,您可以保留要比较的列
ON (target.Id = source.Id AND target.a1 = Source.a1...) -- More join
在SSIS
您可以使用 LOOKUP 转换查找匹配和不匹配的记录,然后插入或删除记录。
在任何情况下,如果您在比较源 table 与目标和更新时考虑所有列,那将毫无意义。
我正在使用 SSIS 包将数据从 SQL 服务器复制到 Oracle,我想通过增量更新提高复制性能。
我的想法是:
- 追加 table 的新记录。(在追加之前删除它们)
- 删除 "Deleted" 条记录
代码:
drop table A1
drop table A2
--Old Table
create Table A1(id int,
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
--New Table
create Table A2(id int,
a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
insert into A1 (id, a1, a2, a3, a4, a5, a6, a7, a8)
values (1,1,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8),
(4,3,1,3,4,5,7,3,8)
insert into A2 (id, a1, a2, a3, a4, a5, a6, a7, a8)
values (1,2,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8)
--1) Changed values
select * from a2
except
select * from a1;
--2) "Deleted" Values. If I Have primary key in A1,A2 the result is simply get by query
select a1.*
from A1
left join A2 on a2.id = a1.id
where a2.id is null
但在我的真实情况下,我的 table 上没有主键。我如何通过另一种方式实现 2 点,而不通过主键连接?
查询结果:
id a1 a2 a3 a4 a5 a6 a7 a8
1 2 2 3 4 5 6 7 8
id a1 a2 a3 a4 a5 a6 a7 a8
4 3 1 3 4 5 7 3 8
您可以使用 CDC 或其他基于日志文件而不是查询的日志传送机制。如果您仍想将 SSIS 用于查询 -
您是否尝试过在 SQL 服务器上使用 rowversion 来查找差异,它会比 [=21= 更快]当然除外。
select * from a2 where rowversion > @lastmaxrowversion;
发现删除是一件很难的事,你能做的最好的就是
select a1.id from a1 where not exists (select top 1 1 from a2 where a1.id = a2.id);
如果您可以添加删除触发器并将 ID 保存在 table 中,那也很好。
- 请记住,许多公司并不真正关心他们的 ETL 过程中删除的记录,因为存储不再是个问题。此外,如今您可以使用分区 table 归档或活动标志设计不删除的系统。无论如何,如果删除仍然很重要,可以尝试为 insert/update 与删除设置不同的间隔。例如,每 10 分钟检查一次 insert/update,其中每 24 小时删除一次。
通过使用 MERGE 语句,您可以在单个操作中执行 INSERT、UPDATE 和 DELETE,这是增量加载的理想选择。
示例代码:
MERGE A2 AS target
USING (SELECT * FROM A1) AS source
ON (target.Id = source.Id AND target.a1 = Source.a1...) -- More join condition
WHEN MATCHED THEN
UPDATE SET a2 = source.a2, a3 = source.a3 ------ more columns
WHEN NOT MATCHED THEN
INSERT (Id, A1, a1, a2....)
VALUES (source.Id, source.a1, source.a2.....)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
END;
MERGE 语句还提供了捕获插入、删除和更新记录的灵活性(以防万一,您需要它们进行日志记录),但在您真正需要这些信息之前我不推荐它们。
在上面的查询中,您可以保留要比较的列
ON (target.Id = source.Id AND target.a1 = Source.a1...) -- More join
在SSIS
您可以使用 LOOKUP 转换查找匹配和不匹配的记录,然后插入或删除记录。 在任何情况下,如果您在比较源 table 与目标和更新时考虑所有列,那将毫无意义。