Sql server 为什么打开第二个ADO客户端记录集的速度如此之慢?
ReproSql server 为什么打开第二个ADO客户端记录集的速度如此之慢?,sql-server,vba,ms-access,ado,Sql Server,Vba,Ms Access,Ado,Repro 创建包含大量行的SQL Server表: CREATE TABLE largetable (field int); INSERT INTO largetable (field) SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY t1.number) FROM master..spt_values t1 CROSS JOIN master..spt_values; 创建新的VBA项目(例如Access或Excel 2016),并添加对“
CREATE TABLE largetable (field int);
INSERT INTO largetable (field)
SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY t1.number)
FROM master..spt_values t1 CROSS JOIN master..spt_values;
Public Sub Repro()
Dim cn作为新的ADODB.连接
将r1调整为新ADODB.Recordset
cn.ConnectionString=“驱动程序={SQL Server本机客户端11.0};服务器=…;数据库=…;受信任的_连接=是”
中国公开赛
可读cn'Fast(0.01-0.03s)
r1.CursorLocation=adUseClient
r1.打开“选择1”,cn,adOpenStatic
可读cn'慢速(6-10秒)
r1.关闭
可读cn'慢速(6-10秒)
设置r1=无
可读cn'Fast(0.01-0.03s)
cn.Close
端接头
私有子可读(ByVal cn作为ADODB.Connection)
d为双色
将r2调整为新的ADODB.Recordset
d=计时器
r2.CursorLocation=adUseClient
r2.打开“从大表中选择字段”,cn,adOpenStatic
打印计时器-d
r2,结束
设置r2=无
端接头
问题 如您所见,如果另一个客户端游标已经打开,则打开另一个客户端游标的速度会非常慢。我想知道为什么会发生这种情况,以及我能做些什么
更多详细信息 使用SQL Server Profiler,我可以看到“慢”和“快”场景有所不同 这就是“快速”查询的外观:
SQL:BatchStarting SELECT field FROM largetable
SQL:StmtStarting SELECT field FROM largetable
SQL:StmtCompleted SELECT field FROM largetable
SQL:BatchCompleted SELECT field FROM largetable
RPC:Starting
declare @p1 int
set @p1=0
declare @p3 int
set @p3=16388
declare @p4 int
set @p4=8193
declare @p5 int
set @p5=0
exec sp_cursoropen @p1 output,N'SELECT field FROM largetable',@p3 output,@p4 output,@p5 output
select @p1, @p3, @p4, @p5
RPC:Completed
...same SQL as above...
RPC:Starting exec sp_cursorfetch 180150003,2,0,1
RPC:Completed exec sp_cursorfetch 180150003,2,0,1
RPC:Starting exec sp_cursorfetch 180150003,2,0,1
RPC:Completed exec sp_cursorfetch 180150003,2,0,1
RPC:Starting exec sp_cursorfetch 180150003,2,0,1
RPC:Completed exec sp_cursorfetch 180150003,2,0,1
...repeat 10000 times...
这就是“慢”查询的外观:
SQL:BatchStarting SELECT field FROM largetable
SQL:StmtStarting SELECT field FROM largetable
SQL:StmtCompleted SELECT field FROM largetable
SQL:BatchCompleted SELECT field FROM largetable
RPC:Starting
declare @p1 int
set @p1=0
declare @p3 int
set @p3=16388
declare @p4 int
set @p4=8193
declare @p5 int
set @p5=0
exec sp_cursoropen @p1 output,N'SELECT field FROM largetable',@p3 output,@p4 output,@p5 output
select @p1, @p3, @p4, @p5
RPC:Completed
...same SQL as above...
RPC:Starting exec sp_cursorfetch 180150003,2,0,1
RPC:Completed exec sp_cursorfetch 180150003,2,0,1
RPC:Starting exec sp_cursorfetch 180150003,2,0,1
RPC:Completed exec sp_cursorfetch 180150003,2,0,1
RPC:Starting exec sp_cursorfetch 180150003,2,0,1
RPC:Completed exec sp_cursorfetch 180150003,2,0,1
...repeat 10000 times...
因此,当查询速度快时,所有数据都在一个批次中加载,而当查询速度慢时,每个记录都单独传输
显然,我想强制ADO始终使用“快速”路由,即使另一个客户端游标已经打开
附加注释
- 我知道,
可以返回与请求的游标不同的游标类型。在这种情况下,在Recordset.Open
之后检查rs2.Open
和CursorType
,会发现在这两种情况下(慢和快)都会返回客户端静态光标CursorLocation
- 我已经测试了以下SQL Server ODBC驱动程序,所有这些驱动程序都可以重现此问题:
- “经典”MDAC
ODBC驱动程序{SQL Server}
- SQL Server本机客户端11.0
- 最新的
- “经典”MDAC
- SQL Server OLE DB驱动程序可能会重现此问题。我们使用ODBC而不是OLEDB,因为。我知道它在不久前还没有被弃用,但我们目前不打算迁移我们的DAL
- 启用MARS(
)没有任何区别。SQL Server探查器显示两个记录集使用相同的连接。这是MARS\u Connection=yes
- 我们使用ADO而不是ADO.NET,因为MS Access尚未内置对.NET代码的支持
- 我们不想使用服务器端游标。他们。我们刚从他们那里迁移出去
fast/slow
注释。)本机客户端也是,当前驱动程序是。它不太可能表现出不同的行为,但也许值得一试。谢谢,我明天会试试。(虽然我的直觉告诉我这是ODBC的OLE DB提供程序(MSDASQL)的问题,而不是ODBC驱动程序的问题。)@Andre:我试过了,同样的问题。