首先我要说的是,能够从平面文件中获取1700万条记录,推送到远程盒子上的数据库并花费7分钟是令人惊讶的。 SSIS真的太棒了。但是现在我有那些数据,如何删除重复数据?
更好的是,我想取平面文件,从平面文件中删除重复项并将它们放回另一个平面文件中。
我正在考虑:
Data Flow Task
Thak你,这个网站上的每个人都非常了解。
Update:
I have found this link, might help in answering this question
答案 0 :(得分:22)
使用排序组件。
只需选择要对已加载行进行排序的字段,在左下角,您将看到一个复选框以删除重复项。此框仅根据排序条件删除任何重复的行 因此,在下面的示例中,如果我们仅对第一个字段进行排序,则行将被视为重复:
1 | sample A |
1 | sample B |
答案 1 :(得分:6)
我建议使用SSIS将记录复制到临时表中,然后创建一个根据您的情况使用Select Distinct或Rank的任务来选择将它们汇总到平面文件并从临时表中删除它们的重复项。最后一步是将临时表中的记录复制到目标表中。
确定重复是SQL擅长的,但平面文件不太适合。在您提议的情况下,脚本容器将加载一行,然后必须将其与1700万条记录进行比较,然后加载下一行并重复...性能可能不是那么好。
答案 2 :(得分:4)
平面文件来源 - >聚合(按列要分组) - >平面文件目的地
答案 3 :(得分:2)
策略通常取决于登台表的列数。列越多,解决方案就越复杂。你链接的文章有一些非常好的建议。
我将添加到目前为止所有其他人所说的内容中,唯一的事情就是具有日期和日期时间值的列将提供此处介绍的一些解决方案。
我想出的一个解决方案是:
SET NOCOUNT ON
DECLARE @email varchar(100)
SET @email = ''
SET @emailid = (SELECT min(email) from StagingTable WITH (NOLOCK) WHERE email > @email)
WHILE @emailid IS NOT NULL
BEGIN
-- Do INSERT statement based on the email
INSERT StagingTable2 (Email)
FROM StagingTable WITH (NOLOCK)
WHERE email = @email
SET @emailid = (SELECT min(email) from StagingTable WITH (NOLOCK) WHERE email > @email)
END
在进行重复数据删除时,这比CURSOR快很多,并且不会挂断服务器的CPU。要使用它,请将来自文本文件的每个列分隔为它们自己的变量。在循环之前和之内使用单独的SELECT语句,然后将它们包含在INSERT语句中。这对我来说非常好。
答案 4 :(得分:2)
要在平面文件上执行此操作,我使用unix命令行工具sort:
sort -u inputfile > outputfile
不幸的是,windows sort命令没有唯一的选项,但您可以尝试从以下选项之一下载排序实用程序:
(我没试过,所以没有保证,我害怕)。
另一方面,要在将记录加载到数据库中时执行此操作,可以在数据库表上使用ignore_dup_key创建唯一索引。这将使记录在加载时非常有效。
CREATE UNIQUE INDEX idx1 ON TABLE (col1, col2, ...) WITH IGNORE_DUP_KEY
答案 5 :(得分:2)
一些肮脏的解决方案是使用跨越所有列的复合键设置目标表。这将保证distint唯一性。然后在“数据目标”形状上,配置任务以忽略错误。所有重复的插入都将被遗忘。
答案 6 :(得分:2)
我们可以使用查找表。像SSIS一样提供两个DFS(数据流转换),即模糊分组和模糊查找。
答案 7 :(得分:1)
我建议在目标服务器上加载登台表,然后将结果合并到目标服务器上的目标表中。如果您需要运行任何卫生规则,那么您可以通过存储过程执行此操作,因为您必须获得比通过SSIS数据流转换任务更好的性能。此外,重复数据删除通常是一个多步骤的过程。你可能想要重复数据删除:
WITH
sample_records
( email_address
, entry_date
, row_identifier
)
AS
(
SELECT 'tester@test.com'
, '2009-10-08 10:00:00'
, 1
UNION ALL
SELECT 'tester@test.com'
, '2009-10-08 10:00:01'
, 2
UNION ALL
SELECT 'tester@test.com'
, '2009-10-08 10:00:02'
, 3
UNION ALL
SELECT 'the_other_test@test.com'
, '2009-10-08 10:00:00'
, 4
UNION ALL
SELECT 'the_other_test@test.com'
, '2009-10-08 10:00:00'
, 5
)
, filter_records
( email_address
, entry_date
, row_identifier
, sequential_order
, reverse_order
)
AS
(
SELECT email_address
, entry_date
, row_identifier
, 'sequential_order' = ROW_NUMBER() OVER (
PARTITION BY email_address
ORDER BY row_identifier ASC)
, 'reverse_order' = ROW_NUMBER() OVER (
PARTITION BY email_address
ORDER BY row_identifier DESC)
FROM sample_records
)
SELECT email_address
, entry_date
, row_identifier
FROM filter_records
WHERE reverse_order = 1
ORDER BY email_address;
对于重复数据删除文件有很多选项,但最终我建议您在目标服务器上加载临时表后在存储过程中处理此问题。清理数据后,您可以MERGE或INSERT进入最终目的地。
答案 8 :(得分:1)
发现此页面link text可能值得一看,但有1700万条记录可能需要一段时间太长