我有C#代码,它从数据库A上的SELECT返回一个DataTable,并通过Microsoft.Practices.EnterpriseLibrary.Data.
Database.ExecuteDataSet方法将它作为表值参数传递给数据库B上的存储过程.表中有大约200K行.在我们的测试环境中,A和B位于同一台服务器上,执行存储过程只需几秒钟.但在生产中,ExecuteDataSet调用大约需要30分钟.检查数据库日志表明,在ExecuteDataSet调用的开始和存储过程的开始之间几乎消耗了所有时间.
在测试中,两个数据库都在一台服务器上.在生产中,A和B位于不同的服务器上.
什么可能导致这种极端延迟,可以做些什么呢?仅在对生产服务器运行时才会发生这种情况.它已在多个测试环境中运行,没有任何问题.
2016/04/08更新
如果表值参数作为IEnumerable< SqlDataRecord>传递,则性能是合理的.而不是DataTable.使用SqlDataRecord需要7秒才能传递50,000条记录,而使用DataTable需要400秒.问题与服务器有关.使用DataTable将相同数量的数据传递给另一台服务器,没有任何问题.
最佳答案 我们也遇到了这个问题.来自Kevin Cline的最新发现帮助我们弄清楚为什么它会在一台服务器上快速运行而在另一台服务器上运行速度极慢:
The performance is reasonable if the table-valued parameter is passed
as IEnumerable instead of DataTable. It takes 7 seconds
to pass 50,000 records to using SqlDataRecord, but 400 seconds using
DataTable. The problem is server-dependent. The same volume of data is
passed to another server using DataTable with no problem.
我们发现使用SQL Server设置ForceEncryption是快速执行服务器和性能低下的服务器之间的区别.如果ForceEncryption设置为Yes,则表现不佳;如果设置为No,则表现良好.此设置位于SQL Server配置管理器中 – > SQL Server网络配置 – >右键单击Protocols – > SelectProperties – >证书标签 – >选择你的证书 – >标签标签.
因此,要解决此问题,您有两种选择.要么关闭数据库上的ForceEncryption设置(可能不建议),要么避免使用DataTables,而是转而使用Kevin Cline建议的SqlDataRecords.