29

我已经有这个问题几个星期了。问题是查询在网站上运行需要 4-5 分钟,而在 ssms 中运行最多需要 2 或 3 秒。我还发现,在更改此查询(例如添加 customerId 变量)后,它将开始在网页上快速运行,但到第二天又变慢了。有问题的查询是这个:

DECLARE @customerID INT
SET @customerID = @CustID
DECLARE @MyTable table(
Iden int NOT NULL IDENTITY(1,1),
ProductID int)

INSERT INTO @MyTable(ProductID)
SELECT P.ProductID FROM Product P WITH (NOLOCK)
left join Compunix_ProductMMY cpmmy with (nolock) on p.ProductID = cpmmy.ProductID
left join Compunix_CustomerMMY ccmmy with (nolock) on ccmmy.mmyid = cpmmy.mmyid
WHERE P.Deleted=0 AND P.Published=1 and (ccmmy.customerid = @customerID OR cpmmy.productid IS NULL)

SELECT c.Name, c.SeName, c.CategoryID
FROM Category c WITH (NOLOCK) 
JOIN ProductCategory PC With (NOLOCK) ON C.CategoryID = PC.CategoryID
JOIN @MyTable MT ON PC.ProductID=MT.ProductID
WHERE C.Published = 1
GROUP BY c.Name, c.SeName, c.CategoryID
ORDER BY c.Name

我在其他 2 个网站上运行了相同的查询,它们工作得很好。站点之间的唯一区别是它们在不同的数据库上运行,与其他 2 个相比,慢速站点上的产品(54000 种产品)多一倍多。所有三个站点及其数据库都托管在同一台机器上.

4

7 回答 7

31

您可能遇到了参数嗅探的问题。

我建议阅读应用程序中的慢,SSMS 中的快?由 Erland Sommarskog 全面了解该问题(文章很长,但非常好)。

于 2012-04-16T13:52:36.937 回答
12

查看 sys.dm_exec_sessions 用于您的 ASP.Net 应用程序和 SSMS 会话。我会冒险猜测您的设置中至少有一个SET是不同的。这可能会促成不同的计划(最终这归因于参数嗅探),并且应用程序端通常会变得更糟。

有关更多详细信息,请参阅这些其他问题:

从 Web 调用存储过程时速度慢,从 Management Studio 调用时速度快

过程在 ADO.NET 中超时,但在 SSMS 中没有

从 Web 执行时查询超时,但从 SSMS 执行时超快

ADO .NET 与 SQL Server Management Studio - ADO 性能更差

于 2012-04-16T13:59:37.277 回答
7

我有同样的问题,在我的情况下它与 MARS 有关,所以我MultipleActiveResultSets=True;从连接字符串中删除,现在 SSMS 和 asp.net 的运行时间几乎相同(0.2s 与之前的 4.5s 相比)

注意:MARS = 多个活动结果集。如果在连接字符串上设置此属性,则可以以交错方式在同一连接上运行多个查询。它的主要目的是允许您在遍历结果集时提交 UPDATE 语句。

于 2018-08-13T14:15:15.780 回答
2

同时执行以下步骤对我有用。

  1. 尝试存储过程重新编译
  2. 清除计划缓存
  3. 更新数据库上的统计信息
于 2021-03-17T17:31:09.700 回答
1

不管它的价值是什么,我们偶尔会遇到同样的问题;可能一年一次。您可以花一周的时间阅读和消化其他答案中提到的所有精彩资源,或者您可以像我们一样做;停止并启动 SQL Server。

这是一种享受。

我们注意到这个问题通常发生在各种可能与手头问题没有直接关系的 schema/sp/view mods 之后。

于 2013-06-25T10:44:03.257 回答
0

表变量和临时表在查询执行中有很大的不同

我不确定你为什么使用 table 变量你可以试试这个代码,看看是否能解决你的缓慢之谜

DECLARE @customerID INT
SET @customerID = @CustID

SELECT c.Name, c.SeName, c.CategoryID
FROM Category c WITH (NOLOCK) 
JOIN ProductCategory PC With (NOLOCK) ON C.CategoryID = PC.CategoryID
JOIN (SELECT P.ProductID FROM Product P WITH (NOLOCK)
        left join Compunix_ProductMMY cpmmy with (nolock) on p.ProductID = cpmmy.ProductID
        left join Compunix_CustomerMMY ccmmy with (nolock) on ccmmy.mmyid = cpmmy.mmyid
        WHERE P.Deleted=0 AND P.Published=1 and (ccmmy.customerid = @customerID OR cpmmy.productid IS NULL)
        ) MT ON PC.ProductID=MT.ProductID
WHERE C.Published = 1
GROUP BY c.Name, c.SeName, c.CategoryID
ORDER BY c.Name
于 2021-04-28T17:31:18.983 回答
0

你在使用任何 ORM 吗?如果您使用 NHibernate,您可以在 NHibernate 中启用数据库跟踪,看看可能是什么问题。以下是我在此类场景中观察到的一些场景:

  1. 导致错误计划选择的隐式转换(nvarchar被使用而不是varchar)。您可以在其日志中观察 NHibernate 参数映射。
  2. 缺乏索引。

NHibernate 使用 log4net,您只需要添加一个附加程序,如此处所述

于 2018-08-13T22:44:41.583 回答