考虑来自MS Access的以下VBA代码:
Private Declare Function GetTickCount Lib "kernel32" () As Long
Sub QuickTest()
Dim s As Long: s = GetTickCount
Dim cn As Object
Set cn = CreateObject("ADODB.Connection")
cn.ConnectionString = "Provider=sqloledb;Server=10.54.146.90,14330;" & _
"Database=MyDb;Integrated Security=SSPI;"
cn.Open
Debug.Print GetTickCount - s; " ms elapsed (Version " & cn.Version & ")"
End Sub
我在两个不同的系统上运行上面的代码,一个使用Windows 10和SQLOLEDB / ADODB版本10:
16593 ms elapsed (Version 10.0)
9500 ms elapsed (Version 10.0)
9485 ms elapsed (Version 10.0)
9469 ms elapsed (Version 10.0)
另一个使用Windows 7和SQLOLEDB / ADODB版本6.1:
967 ms elapsed (Version 6.1)
531 ms elapsed (Version 6.1)
515 ms elapsed (Version 6.1)
531 ms elapsed (Version 6.1)
为什么 SQLOLEDB / ADODB版本10 需要几乎二十倍来打开与 SQLOLEDB / ADODB版本6.1 相同的数据库的连接?这是SQLOLEDB / ADODB版本中的错误,已知问题还是其他问题?我仍然可以在Windows 10计算机上使用6.1版本吗?
更多信息:我只是从Access中的即时窗口调用此功能。两个系统都是64位Windows。两个系统都是32位MS Access。 Win 7机器正在使用MS Access XP(即2002年)。 Win 10计算机正在使用MS Access 2013.两台计算机都连接到同一LAN。正在通过VPN访问远程SQL Server。
为了实现MCVE,我还提出了以下VB脚本。这与上面的代码类似,但针对SQL Server的本地实例运行(将以下代码复制并粘贴到名为AdoSpeedTest.vbs的文件中):
s = Timer()
Set cn = CreateObject("ADODB.Connection")
cn.ConnectionString = "Provider=sqloledb;Server=.;Database=master;Integrated Security=SSPI;"
cn.Open
et = (Timer() - s) * 1000
WScript.Echo Round(et) & " ms elapsed (Version " & cn.Version & ") "
如果我在禁用TCP / IP的本地SQL Server Express实例上运行AdoSpeedTest.vbs,则平均需要大约4-5秒。如果我在本地实例上启用TCP / IP,则平均需要大约16 - 25 ms 。在两种情况下都正确地打开了连接(我用一个检索数据库表内容的较长脚本验证了这一点),当TCP / IP被禁用时,它只需要更长的时间。
我在两种情况下(本地SQL Server TCP / IP启用和禁用)都测试了与SQL Server的远程连接,但这似乎对在远程服务器上创建连接时的性能没有影响。
更新2 :使用ProcMon进一步调查后,我发现远程连接使用两种不同的协议进行连接。慢速连接使用UDP,更快的连接使用TCP。为什么一个连接使用UDP而另一个连接使用TCP连接到同一个远程服务器?本地防火墙是否存在阻止我使用非默认SQL Server端口的问题?
更新3:远程连接都使用TCP。与UDP的混淆可能是由于使用ProcMon所固有的所有噪音。
我尝试在数据库服务器上运行WireShark,然后从ADO 6.1和ADO 10连接到数据库。花了几个小时来筛选噪音之后,仍然存在以下重要区别:
在较慢的版本中,有两个额外的[ACK] - 仅包,每个包产生4.5秒的延迟。
这是快速连接的TCP流的WireShark屏幕截图:
这是一个慢速连接TCP流的WireShark屏幕截图:
请注意数字355和515之后引入的延迟。