转置的性能问题并将大型可变列数据文件插入SQL Server

时间:2010-06-25 10:52:03

标签: c# sql-server ssis performance

我目前正在开发一个项目,我们有一个大型数据仓库,每天从许多不同的来源导入数GB的数据。我们有很多不同格式和结构的文件都被导入到几个基表中,然后我们通过存储过程转置/转移。这部分工作正常。然而,最初的导入速度非常慢。

我们不能使用SSIS文件连接管理器,因为列可能在文件之间完全不同,因此我们在C#中有一个自定义对象模型,它将行和列的数据转换为两个基表;一个用于列名,另一个用于每个单元格中的实际数据,与属性表中的记录相关。

示例 - 数据文件:

alt text http://i50.tinypic.com/2ypkgf9.jpg

示例 - 数据库表:

alt text http://i45.tinypic.com/2iqhkoy.jpg

当前通过循环遍历所有数据行并将值附加到SQL字符串来执行SQL插入。这构造了一个大的动态字符串,然后通过SqlCommand在最后执行。

问题是,即使在1MB文件中运行大约需要一分钟,因此当涉及大文件(200MB等)时,处理单个文件需要数小时。我正在寻找有关其他方法的建议,以提高性能并加快流程。

我可以用循环结构做一些事情来减少字符串大小和字符串中存在的SQL命令的数量,但理想情况下我正在寻找更清晰,更强大的方法。如果我没有很好地解释自己,我会尽力提供更多详细信息。

关于如何加快这一过程的任何想法?

3 个答案:

答案 0 :(得分:1)

有一个想法 - 你是否反复回到数据库找到合适的属性值?如果是这样,将重复的查询切换为针对您保留在客户端的记录集的查询将极大地加速。

这是我以前做过的事情 - 涉及4个参考表。创建本地记录集并根据需要进行过滤会导致进程从2.5小时加速到大约3分钟。

答案 1 :(得分:1)

动态字符串将变为SLOW。每个SQLCommand都是对数据库的单独调用。作为批量插入操作,您将 更好地将输出流式传输。

我知道您的所有文件都是不同的格式,因此您必须解析并取消代码才能将其转换为您的EAV数据库格式。

但是,因为输出是一致的模式,所以最好使用单独的连接管理器和内置的unpivot运算符,或者在脚本任务中向公共输出中的数据流添加多行(就像您目前正在为每个输入行构建SQL INSERT ... INSERT ... INSERT,然后将它们全部流入目标。

即。读取您的数据并在脚本源中,将FileID,RowId,AttributeName和Value分配给多行(这样就可以在代码中执行unpivot,但不是生成不同数量的插入,而是插入不同数量的行基于输入行进入数据流。)

然后通过查找传递它以从AttributeName获取到AttributeID(错误地使用无效属性的行)。

直接流入OLEDB目的地,它应该快得多。

答案 2 :(得分:1)

为什么不在每个数据库中存储所需的任何引用表并在数据库端执行所有查找?或者将表类型传递到需要密钥的每个数据库,将所有参考数据存储在一个中央数据库中,然后在那里执行查找可能更好。