在SQL Server上使用并行插入语句

时间:2016-07-29 07:29:23

标签: sql-server go sql-server-2016

我的应用程序:我在Go中编写了一个脚本,通过FTP获取大量(> 10k)JSON文件,并将内容写入本地SQL Server 2016实例中的表。导入文件夹后,它会触发一个T-SQL过程,处理进一步的数据处理。 总的来说,这个解决方案似乎运作良好。但是,我需要高度并行操作才能获得足够的性能。通常,每个文件大约有2,000个条目,我需要为每个文件夹导入大约5,000个文件。 SQL Server在本地运行,语句的性能不是问题。

执行结构:通过FTP检索文件列表,并将每个文件名移交给Goroutine。 go例程获取文件(也通过FTP),解析它并触发SQL插入。在应用程序开始时准备一个简单的insert语句(“INSERT INTO tbl(val1,val2,val3)SELECT $ 1,$ 2,$ 3”)然后在Goroutine中执行( stmt每个条目的.Exec(var1,var2,var3))。 我用通道变量控制最大运行例程数( make(chan bool,MAXPAR),其中MAXPAR = 10但应该是30)。

问题:每当我启动超过15个并行例程(30个最佳)时,我会在一段时间后得到以下错误(~1k文件)

  

在127.0.0.1:1433建立与SQL Server的连接时发生了与网络相关或特定于实例的错误。通常只允许使用每个套接字地址(协议/网络地址/端口)。

我可以在网上找到这可能表明TCP / IP堆栈耗尽(?),但还没找到我的问题的解决方案。由于代码的结构,只有30个语句(当MAXPAR设置为30时)将同时执行,因此问题不应该是连接数。据我所知,可能不是并行度,而是每秒执行次数是限制因素。

我的想法:目前,我可以想到三种可能有所帮助的方案:

  • 将MAXPAR限制为10.但是,这导致性能不佳,我不知道问题最终是否会在该设置下发生
  • 在程序开始时建立更多连接,并随机为每个连接例程分配一个连接。这会降低执行/连接的数量,但是如果每秒执行的总数是个问题,我不确定它是否能解决我的问题。
  • 使用批量语句的形式为每个文件发送一个插入语句,而不是每个条目发送一个。

最后一个选项是目前唯一一个我相信它可行的选项。但是,由于我有类似的插入脚本(到目前为止没有出现问题),我宁愿了解底层问题,如果有办法在我去更改所有应用程序之前阻止它。

问题:我的问题是,如果有人在遇到此问题时有经验(即可以预测),并且上述解决方案之一(或其他解决方案)可以根据您的经验运作。如果它只是一个脚本,我只是尝试所有的解决方案,但由于还有其他脚本,我不确定他们是否会遇到类似的问题,我想找到一个我可以合理肯定的解决方案这已经解决了。

系统

  • Windows 10 x64
  • SQL Server 2016 Developer Edition(x64)
  • 去1.6
  • 图书馆:github.com/denisenkom/go-mssql

由于

1 个答案:

答案 0 :(得分:0)

我对在仅支持10个“连接”的客户端操作系统上运行的SQL Server Developer Edition进行了这种模糊的回忆。我的内存和互联网搜索还没有真正确定这是并发连接,并发查询还是其他什么。围绕该主题有很多讨论。如果它适用于10而不是11,我会说这是你所面临的限制。