当前位置:  开发笔记 > 数据库 > 正文

SqlDataAdapter.Fill方法慢

如何解决《SqlDataAdapter.Fill方法慢》经验,为你挑选了2个好方法。

为什么在SQL Server Management Studio中运行<1秒时,使用此代码返回具有9列,89行的表的存储过程需要60秒才能执行(.NET 1.1)?它在本地计算机上运行,​​因此很少/没有网络延迟,快速开发机器

Dim command As SqlCommand = New SqlCommand(procName, CreateConnection())
command.CommandType = CommandType.StoredProcedure
command.CommandTimeout = _commandTimeOut
Try
   Dim adapter As new SqlDataAdapter(command)
   Dim i as Integer
   For i=0 to parameters.Length-1
      command.Parameters.Add(parameters(i))
   Next
   adapter.Fill(tableToFill)
   adapter.Dispose()
Finally
   command.Dispose()
End Try

我的参数数组是打字的(对于这个SQL,它只是一个参数)

parameters(0) = New SqlParameter("@UserID", SqlDbType.BigInt, 0, ParameterDirection.Input, True, 19, 0, "", DataRowVersion.Current, userID)

存储过程只是一个select语句,如下所示:

ALTER PROC [dbo].[web_GetMyStuffFool]
   (@UserID BIGINT)
AS
SELECT Col1, Col2, Col3, Col3, Col3, Col3, Col3, Col3, Col3
FROM [Table]

RoadWarrior.. 47

首先,确保正确分析性能.例如,从ADO.NET运行两次查询,看看第二次是否比第一次快得多.这消除了等待应用程序编译和调试基础架构升级的开销.

接下来,检查ADO.NET和SSMS中的默认设置.例如,如果在SSMS中运行SET ARITHABORT OFF,您可能会发现它现在运行速度与使用ADO.NET时一样慢.

我曾经发现的是SSMS中的SET ARITHABORT OFF导致重新编译存储过程和/或使用不同的统计信息.突然间,SSMS和ADO.NET都报告了大致相同的执行时间.

要检查这一点,请查看每次运行的执行计划,特别是syscacheobjects表.他们可能会有所不同.

在特定存储过程上运行"sp_recompile"将从缓存中删除关联的执行计划,从而使SQL Server有机会在下次执行该过程时创建可能更合适的计划.

最后,您可以尝试使用SSMS清除整个过程缓存和内存缓冲区的" 从轨道上进行核武器 "方法:

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

在测试查询之前执行此操作可防止使用缓存的执行计划和先前的结果缓存.



1> RoadWarrior..:

首先,确保正确分析性能.例如,从ADO.NET运行两次查询,看看第二次是否比第一次快得多.这消除了等待应用程序编译和调试基础架构升级的开销.

接下来,检查ADO.NET和SSMS中的默认设置.例如,如果在SSMS中运行SET ARITHABORT OFF,您可能会发现它现在运行速度与使用ADO.NET时一样慢.

我曾经发现的是SSMS中的SET ARITHABORT OFF导致重新编译存储过程和/或使用不同的统计信息.突然间,SSMS和ADO.NET都报告了大致相同的执行时间.

要检查这一点,请查看每次运行的执行计划,特别是syscacheobjects表.他们可能会有所不同.

在特定存储过程上运行"sp_recompile"将从缓存中删除关联的执行计划,从而使SQL Server有机会在下次执行该过程时创建可能更合适的计划.

最后,您可以尝试使用SSMS清除整个过程缓存和内存缓冲区的" 从轨道上进行核武器 "方法:

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

在测试查询之前执行此操作可防止使用缓存的执行计划和先前的结果缓存.


DBCC DROPCLEANBUFFERSDBCC FREEPROCCACHE解决了我的问题.这是否需要定期运行,或者仅在对存储过程进行更改时运行?
它是经常性的,因为这些是缓存的结果和计划将逐渐积累.

2> Steve Wright..:

这是我最终做的事情:

我执行了以下SQL语句来重建数据库中所有表的索引:

EXEC ..sp_MSforeachtable @command1='DBCC DBREINDEX (''*'')', @replacechar='*'
-- Replace  with the name of your database

如果我想在SSMS中看到相同的行为,我就像这样运行proc:

SET ARITHABORT OFF
EXEC [dbo].[web_GetMyStuffFool] @UserID=1
SET ARITHABORT ON

绕过这个的另一种方法是将其添加到您的代码中:

MyConnection.Execute "SET ARITHABORT ON"

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有