我正在阅读并验证通过我们的ASP.net网站(用VB.Net编码)提交的大型固定宽度文本文件(范围从10-50K行)。我对文件进行了初始扫描,以检查基本问题(行长等)。然后我将每行导入MS SQL表。每个数据库行基本上由record_ID(主要,自动递增)和大约50个varchar字段组成。
插入完成后,我在文件上运行验证函数,该函数根据一系列标准(修剪长度,数字,范围检查等)检查每行中的每个字段。如果在任何字段中发现错误,它会将记录插入到Errors表中,该表具有error_ID,record_ID和错误消息。此外,如果字段以特定方式失败,我必须在该字段上执行“重置”。重置可能包括消隐整个字段,或者只是将值替换为另一个值(例如,将字符串替换为具有所有非法字符取出的新字符串。)
我有5000行测试文件。上传,初始检查和导入大约需要5-6秒。详细的错误检查并插入Errors表大约需要5-8秒(此文件中有大约1200个错误)。但是,对于需要重置的750个字段,“重置”部分大约需要40-45秒。当我注释掉重置函数(立即返回而没有实际调用UPDATE存储过程)时,过程非常快。打开重置后,页面需要50秒才能返回。
我的UPDATE存储过程正在使用http://sommarskog.se/dynamic_sql.html中的一些推荐代码,它使用CASE而不是动态SQL:
UPDATE dbo.Records
SET dbo.Records.file_ID = CASE @field_name WHEN 'file_ID' THEN @field_value ELSE file_ID END,
.
. (all 50 varchar field CASE statements here)
.
WHERE dbo.Records.record_ID = @record_ID
我有什么方法可以帮助我在这里表现。我能以某种方式将所有这些UPDATE调用分组到一个事务中吗?我应该以某种方式重新处理UPDATE查询吗?或者只是750+ UPDATE的数量而且速度很慢(它是一个带有8GB内存的四进制服务器)。
任何建议表示赞赏。
答案 0 :(得分:2)
不要在sql中执行此操作;在代码中修复数据,然后进行更新。
如果您有sql 2008,那么请查看表值参数。它使您能够将整个表作为参数传递给s'proc。从他们那里你只需要一个插入/更新或合并声明
答案 1 :(得分:1)
如果循环并执行单独的更新/插入,这可能非常昂贵...请考虑使用 SqlBulkCopy ,这可以加快所有插入速度。同样,您可以创建 DataSet ,对数据集进行更新,然后通过 SqlDataAdapter 一次性提交。
答案 2 :(得分:0)
我相信你在每次更新时都会做50个案例陈述。听起来很慢。
通过参数化查询和字符串常量表注入证明代码可以解决这个问题。
快速而肮脏的示例代码。
string [] queryList = { "UPDATE records SET col1 = {val} WHERE ID={key}",
"UPDATE records SET col2 = {val} WHERE ID={key}",
"UPDATE records SET col3 = {val} WHERE ID={key}",
...
"UPDATE records SET col50 = {val} WHERE ID={key}"}
然后在调用SQL时,只需选择与要更新的col对应的数组中的项目,并为参数化项目设置值和键。
我猜你会看到一个重大改进...让我知道它是怎么回事。
答案 3 :(得分:0)
庵。为什么要将数字数据插入VARCHAR字段然后尝试对其进行数字检查?这太可惜了。
对表格应用正确的数据类型和约束,执行INSERT,并查看它是否失败。 SQL Server很乐意向您报告错误。
答案 4 :(得分:-1)
我会尝试将恢复模型更改为简单并查看我的索引。金伯利·特里普(Kimberly Tripp)做了一个会议,展示了使用堆改善性能的方案。