从HUGE表中删除“非唯一”值的“最佳实践”是什么?

时间:2010-09-09 15:58:14

标签: sql-server sql-server-2005 distinct

步骤1:通过“批量插入”将数据从.txt(分隔)文件加载到表1中(无索引等)

bulk insert Table_1
from '\\path\to_some_file.txt'
with ( tablock, FORMATFILE ='format_file_path.xml') 

通过格式文件I映射输出列数据类型以避免进一步转换(例如从Char到Int)

步骤2:将结果(可能不是表1中的所有列)输出到另一个表2中,但只输出表1中的DISTINCT值。

NB!表1是 2000万条记录 (每次加载)。

我们现在拥有的(示例简化):

select distinct convert(int, col1), convert(int, col2), col3, ... 
into Table_2
from Table_1

处理需要大约3.5分钟。 您能否建议一些可能有助于缩短处理时间并将只有UNIQUE记录放入Table_2的最佳实践?

提前致谢!

UPD 1 :对不起误解 - 我的意思是选择不同的查询需要3.5分钟。 “批量插入”相当优化 - 它通过8个线程(8个单独的.txt文件)“批量插入”加载到1个表中(TABLOCK)并在大约1分钟内导入20mln记录。

UPD 2:我测试了不同的方法(没有在SSIS上测试 - 在我们的应用程序中,这种方法不起作用): 最好的结果是数据“批量插入”到TABLE_2格式的方法(列类型匹配,数据类型 - 也),因此我们消除了数据类型转换。只是“简单”不同:

select distinct * into Table_2 from Table_1

提供70秒的处理。所以我可以认为这是我现在能得到的最好结果。 我还尝试了几种技术(额外的顺序,CTE胜利分组等) - 它们更糟糕,然后“简单”不同。

感谢大家的参与!

5 个答案:

答案 0 :(得分:2)

您必须知道导致此问题的SELECT DISTINCT是否正确,或INSERT INTO导致问题。

你必须运行SELECT DISTINCT一次,没有INSERT INTO运行一次,并测量持续时间以确定你需要调整哪一个。

如果是您的SELECT DISTINCT,您可以尝试微调该查询以提高效率。

如果是INSERT INTO,请考虑以下事项:

使用INSERT INTO,将创建一个新表,并根据需要分配所有页面。

您是否放弃旧桌子并创建一个新桌子?如果是这样,您应该将其更改为仅从旧表中删除 - DELETE,截断 - 这是因为截断将释放该表获取的所有页面,并且必须重新进行-allocated。

您可以尝试以下一项或多项措施来提高效率。

  1. 向您的客户询问非重复数据
    • 所有重复标准列的索引。扫描索引应该比扫描表快得多。
    • 对您的临时表进行分区以获得更好的性能
    • 创建一个选择不同值的视图,并使用BCP快速加载数据。

答案 1 :(得分:1)

找到那些重复的然后删除,然后复制到table2中。

找到像这样的重复项

SELECT col1, 
COUNT(col1) AS NumOccurrences
FROM table1
GROUP BY col1
HAVING ( COUNT(col1) > 1 )

答案 2 :(得分:0)

这就是SSIS的全部意义,伙计。 :)

<强> [更新]

在SSIS中尝试这一点,看看你能够多快地咀嚼这些数据:

平面文件来源 - &gt;对具有重复删除的组件进行排序 - &gt;平面文件目的地(或带有tablock和东西的Ole Db目的地)

答案 3 :(得分:0)

您的CONVERT语句可能会导致延迟。

答案 4 :(得分:-3)

我建议创建一个游标,该游标遍历所有字段排序的所有行,并使用变量将当前行与前一行进行比较,以检测是否已经看到该行。您可以在此过程中删除重复的行,也可以创建返回关系的过程(抱歉,不知道SQL服务器的确切术语),只包含唯一的行(如果检测到重复,则跳过此行,即不要产生)。