19

System.Data.SqlClient.SqlCommand我有一个存储过程,它从 Sql Server Management Studio 执行(2 秒)比运行时(2 分钟后超时)要快得多。

这可能是什么原因?


详细信息:在 Sql Server Management Studio 中,这将在 2 秒内运行(在生产数据库上):

执行 sp_Stat
    @DepartmentID = 空

在 .NET/C# 中,2 分钟后以下超时(在生产数据库上):

string selectCommand = @"
EXEC sp_Stat
    @DepartmentID = NULL";
string connectionString = "server=***;database=***;user id=***;pwd=***";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    using (SqlCommand command = new SqlCommand(selectCommand, connection))
    {
        connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
            }
        }
    }
}

我也尝试了selectCommand = "sp_Stat",CommandType = StoredProcedure和 an SqlParameter,但结果相同。

没有EXEC它也是一样的结果。

在一个几乎没有数据的开发数据库上,这两种情况都在不到 1 秒的时间内完成。所以这与数据库中有很多数据有关,但它似乎只发生在.NET中......


Marc Gravell 所写的关于不同SET价值观的内容在所呈现的案例中有所不同。

SQL Server Profiler 显示 Sql Server Management Studio 运行以下SET.NET Sql Client Data Provider 没有:


SET ROWCOUNT 0 
SET TEXTSIZE 2147483647 
SET NOCOUNT OFF 
SET CONCAT_NULL_YIELDS_NULL ON 
SET ARITHABORT ON 
SET LOCK_TIMEOUT -1 
SET QUERY_GOVERNOR_COST_LIMIT 0 
SET DEADLOCK_PRIORITY NORMAL 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
SET ANSI_NULLS ON 
SET ANSI_NULL_DFLT_ON ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
SET CURSOR_CLOSE_ON_COMMIT OFF 
SET IMPLICIT_TRANSACTIONS OFF 
SET QUOTED_IDENTIFIER ON
SET NOEXEC, PARSEONLY, FMTONLY OFF

当我包含这些内容时,相同的查询在 SSMS 和 .NET 中花费了相同的时间。负责人SET是...

SET ARITHABORT ON

我学到了什么?也许使用分析器而不是猜测......

(起初的解决方案似乎与参数嗅探有关。但我混淆了一些东西......)

4

4 回答 4

11

另一件可能很重要的事情是启用SET选项。其中一些选项更改查询计划足以更改配置文件。如果您正在查看(例如)计算 + 持久(并且可能索引)列,有些可能会产生巨大影响:如果SET选项不兼容,则可以强制重新计算值,而不是使用索引value - 可以将索引搜索更改为表扫描 + 计算。

尝试使用分析器查看哪些SET选项正在“起作用”,并查看使用这些选项是否会改变事情。

另一个影响是连接字符串;例如,如果您启用 MARS,它可以以微妙的方式改变行为。

最后,事务(隐式 ( TransactionScope) 或显式)可能会产生巨大的影响,具体取决于隔离级别。

于 2009-04-29T11:56:14.900 回答
5

这几乎可以肯定是由于“不正确”的缓存查询计划。这已经出现了好几次了。

你有最新的统计数据吗?定期计划的索引维护计划?

您可以通过将其添加到存储过程定义中来测试它是否肯定是由于缓存的查询计划:

CREATE PROCEDURE usp_MyProcedure WITH RECOMPILE...

这将重新索引整个数据库(如果数据库非常大,请注意!):

exec sp_msforeachtable "dbcc dbreindex('?')"

所以帖子:

Managment Studio 和 TableAdapter 之间存储过程的执行时间差异很大。

SQL Server 中的参数嗅探(或欺骗)

为 SQL Server 2005 优化未知数?

同一个存储过程的不同执行计划

于 2009-04-29T11:35:12.987 回答
1

有一个类似的问题,事实证明,连接字符串中的 MultipleActiveResultSets=true (应该影响最小)使得通过远程连接提取 150 万条记录需要 25 分钟而不是大约 2 分钟。

于 2016-07-28T03:43:40.970 回答
0

我们有一个类似的问题,在 SSMS 中查询将在 2 秒内完成,而从 .NET 客户端调用时则需要 90 多秒(我们编写了几个 VB/C# 应用程序/站点来测试它。)

我们怀疑查询计划会有所不同,并使用显式循环(“内循环连接”和“带索引”)提示重写了查询。这解决了问题。

于 2009-04-29T11:30:44.010 回答