我有一个作为Windows服务运行的导入程序进程(作为应用程序的调试模式),它处理各种xml文档和csv并导入到SQL数据库中。一切顺利,直到我不得不从另一个表处理大量数据(120k行)(就像我做xml文档一样)。
我现在发现SQL服务器的内存使用量正在达到挂起的程度。我的应用程序永远不会从服务器收到时间,一切都停止。
我仍然能够单独调用数据库服务器,但该应用程序线程在SQL活动监视器中没有明显的线程而在Profiler中没有活动。
任何关于从哪里开始解决这个问题的想法都会受到高度赞赏,因为我们一直在努力解决这个问题超过一周。
基本体系结构是使用NHibernate的c#2.0,因为ORM数据被拉入实际的c#逻辑并被处理然后再回到同一个数据库中,同时还有日志到其他表中。
唯一有时会发生的另一个问题是,由于某种原因,光标正在这个庞大的表上打开,我只能假设它是从ADO.net生成的语句,如exec sp_cursorfetch 180153005,16,113602,100根据Profiler
被召唤数千次答案 0 :(得分:1)
你什么时候COMMIT
数据?是否有锁或死锁(sp_who)?如果认为120,000行很大,那么SQL Server使用多少RAM?当应用程序挂起时,是否有任何关于它挂起的点(是INSERT
,查找SELECT
还是什么?)?
在我看来,提交大小太小了。通常在SSIS ETL任务中,对于基数超过1,000,000的窄行,我将使用100,000的批量大小,但是对于非常宽的行,我永远不会低于10,000。
我不会将ORM用于大型ETL,除非转换对于许多业务规则非常复杂。即便如此,通过大量相对简单的业务转换,我会考虑将数据加载到简单的临时表中,并使用T-SQL执行所有插入,查找等。
答案 1 :(得分:0)
您是否使用BCP将其运行到SQL中?如果没有,事务日志可能无法跟上您的输入。在测试计算机上,尝试将恢复模式设置为简单(未记录),或使用BCP方法获取数据(它们绕过T记录)
答案 2 :(得分:0)
加上StingyJack的回答......
如果由于处理要求而无法使用直接BCP,您是否考虑使用工具对单独的SQL Server(单独的框)执行导入,然后运行BCP?
完成这项工作的关键是保持登台机器清洁 - 也就是说,除了当前工作集之外没有数据。这应该保持RAM使用率足以使导入工作,因为你没有用 - 我推测 - 数百万条记录。最终结果将是第二个数据库中的单个视图或表,当所有处理完成时,可以轻松地将BCP转换为真实的数据库。
缺点当然是另一个盒子......还有一个更复杂的架构。而这一切都取决于你的架构,以及是否可以轻松支持这类事情......
我必须使用我自己的一些非常庞大和复杂的进口来做这件事,而且它在过去运作良好。昂贵但有效。
答案 3 :(得分:0)
我发现nHibernate在大表上创建了游标。我还没理解为什么,但同时我用直接的ado.net调用替换了大型表数据访问模型
答案 4 :(得分:0)
由于您无论如何都要重写它,您可能不知道可以通过System.Data.SqlClient.SqlBulkCopy类直接从.NET调用BCP。有关一些有趣的执行信息,请参阅this article。