设置:ASP.net 3.5,Linq-to-Sql。独立的Web和DB服务器(每个8核,8GB RAM)。 4个数据库。我正在运行一个带有几百万条记录到DB4的插入操作(现在使用Linq-to-Sql,尽管我可能会切换到SqlBulkCopy)。记录显示记录以每秒600-700的速率一致地放置(我每1000条记录运行DataContext.SubmitChanges()以保持事务大小不变)。插入在一个Http请求期间运行(超时设置得相当高)。
问题是当这个插入操作正在运行时,Web应用程序变得完全没有响应(在我的机器上的不同浏览器窗口中以及在远程位置的其他浏览器上)。
此插入操作正在触及DB4中的一个表。大多数页面只会触及DB1(所以我不认为这是一个锁定问题 - 我也通过Management Studio签入,没有任何对象被不必要地锁定)。我已经检查了Web和数据库服务器上的性能统计数据,虽然它们可能会不时出现,但在整个插入过程中,它们仍然处于“绿色”状态。
是否有任何关于可能导致应用无响应的想法或有关我应该采取哪些措施以缩小问题的建议?
对建议的回应:
答案 0 :(得分:1)
我的第一个猜测是,您正在使用与您正在进行的插入操作的数据库的可用连接,并且Web应用程序正在等待连接到数据库。
您有几个选择。
另一个选项,有点不太可能,但它可能是Web应用程序执行批量插入,它占用了服务器上其他Web应用程序的所有CPU时间,阻止了使用。如果您还没有这样做,请将应用程序拆分到自己的池中,以便监视其负载。
答案 1 :(得分:1)
我不知道Linq-to-Sql,但NHibernate明确指出将它用于批量插入是一个坏主意。我发现ADO.NET中的数组绑定非常快,Here is an article解释了如何使用Oracle,但它也应该与其他提供程序一起使用。
答案 2 :(得分:1)
似乎在Web应用程序中执行长时间操作是个坏主意(例如,您的IIS服务器可以无缘无故地重新启动您的应用程序)。将您的长应用程序拆分为Web App和Service App。在Service App中进行长时间操作。通过WCF和他们之间进行沟通。管道
答案 3 :(得分:0)
最终解决方案:我将数据插入从LinqToSql更改为通过DataTable使用SqlBulkCopy。我第一次这样做时,在尝试构建一个内存为200万行的DataTable时,我得到了一个OutOfMemory异常。所以我一次添加50,000行,并使用SqlBulkCopy(批量率:10,000)将它们加载到DB中,然后清除DataTable Rows集合。我现在在108秒内获得210万行(大约每秒20,000次;昨晚的费率是L2S每秒平均200次)。随着数据插入性能的提高,应用程序范围内的无响应性已经消失。
答案 4 :(得分:0)
有可能你有一个锁定声明,在你的web应用程序中,在你将数据加载到数据库的整个过程中阻止了一些重要的解析。