SqlDataAdapter.Fill方法慢

时间:2008-10-30 15:53:07

标签: sql-server vb.net .net-1.1

为什么使用此代码返回具有9列,89行的表的存储过程需要60秒才能执行(.NET 1.1)<在SQL Server Management Studio中运行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)

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

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

5 个答案:

答案 0 :(得分: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清除整个过程缓存和内存缓冲区的“nuke it from orbit”方法:

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

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

答案 1 :(得分:5)

这是我最终做的事情:

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

EXEC <databasename>..sp_MSforeachtable @command1='DBCC DBREINDEX (''*'')', @replacechar='*'
-- Replace <databasename> 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"

答案 2 :(得分:2)

我遇到了同样的问题,但是当我在SQL表上重建索引时,它运行正常,所以你可能要考虑在sql server端重建索引

答案 3 :(得分:1)

为什么不把它变成DataReader而不是DataAdapter,看起来你有一个单一的结果集,如果你不打算在数据库中推回更改并且不需要在.NET代码中应用约束你就不应该不要使用适配器。

编辑:

如果您需要它是DataTable,您仍然可以通过DataReader从数据库中提取数据,然后在.NET代码中使用DataReader填充DataTable。这应该比依赖DataSet和DataAdapter

更快

答案 4 :(得分:0)

我不知道“为什么”它本身如此缓慢 - 但正如马库斯指出的那样 - 将Mgmt Studio与填充数据集进行比较的是苹果到橙子。数据集包含很多开销。我讨厌他们,如果我能帮忙的话,千万不要使用它们。

您可能遇到旧版SQL堆栈或其他类似版本不匹配的问题(特别是考虑到您显然也停留在.NET 1.1中)。框架可能会尝试使用数据库等效“反射”来推断架构等等等

要考虑尝试使用不幸的约束,有一件事是使用datareader访问数据库并在代码中构建自己的数据集。您应该可以通过谷歌轻松找到样本。