与SqlCommand一起使用时,为什么某些sql查询要慢得多?

Ole*_*nge 18 .net sql sqlcommand

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

这可能是什么原因?


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

EXEC sp_Stat
    @DepartmentID = NULL

在.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())
            {
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我也试图与selectCommand = "sp_Stat",CommandType = StoredProcedureSqlParameter,但它是同样的结果.

没有EXEC它也是同样的结果.

在几乎数据空的开发数据库中,两个案例都在不到1秒的时间内完成.所以它与数据库中存在大量数据有关,但它似乎只发生在.NET ...


马克·格拉维尔(Marc Gravell)所写的关于不同SET价值观的内容在所呈现的案

SQL Server Profiler显示,Sql Server Management Studio运行以下SET.NET Sql客户端数据提供程序不执行的操作:


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
Run Code Online (Sandbox Code Playgroud)

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

SET ARITHABORT ON
Run Code Online (Sandbox Code Playgroud)

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

(最初的解决方案似乎与参数嗅探有关.但我混淆了一些事情......)

Mar*_*ell 10

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

尝试使用分析器查看SET"正在运行"的选项,并查看使用这些选项是否会改变一些事情.

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

最后,事务(implicit(TransactionScope)或explicit)会产生巨大影响,具体取决于隔离级别.


Mit*_*eat 5

这几乎可以肯定是由于"不正确"的缓存查询计划.这已经出现了很多次.

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

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

CREATE PROCEDURE usp_MyProcedure WITH RECOMPILE...
Run Code Online (Sandbox Code Playgroud)

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

exec sp_msforeachtable "dbcc dbreindex('?')"
Run Code Online (Sandbox Code Playgroud)

SO帖子:

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

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

为SQL Server 2005优化未知?

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