为什么存储过程从代码中运行得很慢,而在 SSMS 中运行得很快?



我正在使用Dapper从我的Web应用程序运行存储过程。我首先从 SSMS 运行了相同的存储过程,以确保一切正常。它从 SSMS 运行在 1-5 秒内。

然后我将脚本复制/粘贴到我的应用程序中,以便通过 Dapper 运行。当我运行应用并单步调试代码时,存储过程运行了 2 分钟以上并超时。这是完全相同的代码。导致差异的原因是什么?

这是我从 SSMS 运行的代码:

DECLARE @RC int
DECLARE @ownerId varchar(50)
DECLARE @type varchar(50)
DECLARE @dateFrom datetime
DECLARE @dateTo datetime
DECLARE @offset int
DECLARE @perPage int
SET @ownerId = '990042064' 
SET @type = 'voice' 
SET @dateFrom = '2018-05-16 00:00:00.000'  --'YYYY-MM-DD hh:mm:ss[.nnn]' 
SET @dateTo = '2018-08-14 23:59:59.000'  --'YYYY-MM-DD hh:mm:ss[.nnn]' 
SET @offset = 0 
SET @perPage = 50
EXECUTE @RC = dbo.IndexSearch @ownerId
,@type
,@dateFrom
,@dateTo
,@offset
,@perPage
GO

这是从我的应用程序运行的代码:

using (IDbConnection db = new SqlConnection(ConnectionStringHelper.ConnectionString))
{
dbRecs = db.Query<IndexRec>(@"
DECLARE @RC int
DECLARE @ownerId varchar(50)
DECLARE @type varchar(50)
DECLARE @dateFrom datetime
DECLARE @dateTo datetime
DECLARE @offset int
DECLARE @perPage int
SET @ownerId = '990042064'
SET @type = 'voice'
SET @dateFrom = '2018-05-16 00:00:00.000'--'YYYY-MM-DD hh:mm:ss[.nnn]'
SET @dateTo = '2018-08-14 23:59:59.000'--'YYYY-MM-DD hh:mm:ss[.nnn]'
SET @offset = 0
SET @perPage = 50
EXECUTE @RC = dbo.IndexSearch @ownerId
, @type
, @dateFrom
, @dateTo
, @offset
, @perPage
", commandTimeout: 120);
}

我什至尝试在几台不同的计算机上运行 SSMS,我总是在 1-5 秒内完成它。我已经从应用程序运行了几次相同的查询,但它总是超时。

脚本本身中是否有任何内容导致执行计划不同?我还从 SSMS 和我的应用使用相同的登录名。

正如Lukasz所提到的,它可能是参数嗅探,也可能是其他东西。

已经有很多问题博客要了解为什么!

http://www.sommarskog.se/query-plan-mysteries.html

或者你可以试试 https://stackoverflow.com/a/12483089/1481690

查看适用于您的 ASP.Net 应用程序的sys.dm_exec_sessions和 用于 SSMS 会话。我会冒险猜测你的至少一个 SET 设置不同。这可能有助于不同的计划 (最终这归因于参数嗅探(和应用程序 侧面通常最终会变得更糟。

尝试此页面中的建议: 我认为参数嗅探可能是一个红鲱鱼,但 ARITHABORT 解决方案可能会起作用。在任何情况下,尝试选择(重新编译(。SQL 查询在 .NET 应用程序中很慢,但在 SQL Server Management Studio 中是即时的

解决方案应基于将存储过程参数分配给局部变量(请查看参数嗅探(。下面我提供了一个链接,指向您可能会发现有用的文章: https://www.tangrainc.com/blog/2007/08/parameter-sniffing/

相关内容

最新更新