将多个插入到一个表中
在这里,我面临一个更具挑战性的问题,并像往常一样打开本网站获得帮助。将多个插入到一个表中
我有一个Web服务执行一些业务逻辑,并最终将结果插入到表中。这工作正常,如果我的应用程序是在最小的负载。
现在,当负载很重时,我的INSERT
SQL语句已超时。我增加了连接超时和命令超时。但问题是调用相同Web方法的线程太多。只是为了提供一些提示,我在重负载下的OPEN sql连接数量达到了500+。仅供参考,每次执行命令后我都会关闭连接。
现在我应该在这里做什么来优化这个东西?
我打算将INSERT
数据存储在数据表中,并将此数据表存储在APPLICATION变量中。每两分钟后,将数据表中的数据插入数据库。
你们有没有其他的想法可以使我的生活更顺畅?
谢谢
编辑
这里有更多的细节,当我在Management Studio运行插入查询
SQL Server分析和编译时间: CPU时间= 0毫秒,经过的时间= 0毫秒。
SQL Server分析和编译时间: CPU时间= 0毫秒,经过时间= 11毫秒。
表'IndexTable1'。扫描计数0,逻辑读取2,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读取读取0.
表'IndexTable2'。扫描计数0,逻辑读取2,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读取读取0.
表'fulltext_index_docidstatus_171147655'。扫描计数0,逻辑读取11,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读取读取0.
表'MAINTABLE'。扫描计数0,逻辑读取28,物理读取4,预读0,lob逻辑读取0,lob物理读取0次,lob预读0
(受影响1行(S))
(1 row(s)affected)
SQL Server执行时间: CPU时间= 0毫秒,经过时间= 69毫秒。
SQL Server分析和编译时间: CPU时间= 0毫秒,经过时间= 0毫秒。
SQL Server执行时间: CPU时间= 0毫秒,经过时间= 0毫秒。
您可以使用专用线程将数据插入数据库。为每个插入语句打开一个新连接没有意义,相反,您可以每隔几秒插入一次大块数据。该线程可以运行在专用的调度程序或计时器上,并且可以使用线程安全队列进行线程间通信。
您是否想过要获得合适的服务器?很抱歉地说,但是完全忽略硬件实现的方式让我认为你的数据库服务器是一个“典型的低端主机”,它本质上不适合运行大多数IO绑定的沉重SQL负载,因此需要高端IO子系统。
我有专用服务器,带有高CPU的4GM RAM(不记得它的细节),只有这个应用程序正在运行服务器 – user867198 2012-01-05 06:46:30
所以,一个玩具(4GB内存是低端机 - 平均桌面内存),可能是一个小桌面级的光盘?你想知道IO超负荷吗?构建数据库服务器的入门指南可能是合适的。如果光盘过载,CPU和数据库大多无关,而普通光盘的速度很慢 - 每秒150到200次操作。 – TomTom 2012-01-05 06:48:21
我不知道这个问题的简单答案。首先,你的计划会进入并发问题,你可能会试图锁定你的数据表等,这可能会造成麻烦。作为一个经验法则,我建议不要在应用程序和数据库服务器之间建立连接。但另一方面,你的开放连接数是500+是不应该发生的。我认为这是你应该关注的问题。我想你的交易是一个很大的交易,并且它运行了几秒钟。尽量减少它。我可以提供将数据写入一个非常简单的未处理数据库表,如编写日志。在定期运行的SQL作业中,从该表中读取并行处理它们。你甚至可以管理一个系统,当它检测到负载时,它会延迟处理。
如果在一个给定的点上有多个类似的插入查询,那么无论我上面的语句如何,都必须考虑System.Data.SqlClient.SqlBulkCopy类。
祝你好运。
我在SQL SP中只有一个Insert语句。我会在SqlBulkCopy命令上给它一个镜头。看起来不错的替代方案 – user867198 2012-01-05 06:50:44
回答这样的疑问,可能会过于复杂
揣摩瓶颈在哪里 - 是@客户或@服务器端。
什么涉及到INSERT指标的量,如果有任何热点你的表的顶部 - 有没有同时选择所执行这对于单分区自动增量主键的表
很平常超过表当插入它时
你应该检查所有这些和许多其他原因,以找出问题出在哪里。
试着在你的问题提供更多有价值的信息
在前端方面同时执行了SELECT语句,但是我所有的SELECT都带有NOLOCK选项。所以我认为它不应该产生任何问题 – user867198 2012-01-05 06:55:41
伊利亚·高根的答案似乎是合理的,它是在同样的你的。基本上按照计划进行批量插入。请记住,只有在您插入的信息本身不用于业务逻辑来响应新请求时,这才会起作用。 当你发出一个响应时,客户端会认为无论服务器状态发生了什么变化,当它决定发出第二个请求时,就会出现两个问题:1)如果响应客户端出于任何原因稍后不能插入该请求的结果? 2)如果收到响应后客户会发出一个新的请求,那么第一个请求的结果仍然不会持续下去会发生什么?应用程序将使用什么数据来处理第二个请求。 正如你所看到的,这个看起来很简单的解决方案可能会导致其他问题,但这一切都取决于你的web服务是如何设计的,特别是如果需要为每个请求保存任何持久数据来处理进一步的请求。
连接池有多大? – Jordan 2012-01-05 06:20:28
您完全需要对您的应用程序进行基准测试,以确定潜在的瓶颈。对于初学者来说,熟悉SQL Server的“解释计划”,检查你的索引,并查看负载下的Windows性能监视器,以检查CPU,RAM和磁盘I/O利用率。请看这些链接:1)http://msdn.microsoft.com/en-us/library/ff647768.aspx 2)http://msdn.microsoft.com/en-us/library/ms178071.aspx – paulsm4 2012-01-05 06:23:36
您是否查看过生产者/消费者模式以处理来自共享上下文的插入,这样您就可以控制连接数并使用SqlBulkCopy。 – Lloyd 2012-01-05 06:24:49