SQL 服务器中的许多操作超时并阻止进程

Many operations time out and block process in SQL Server

我们的站点日志中有很多操作超时。

在服务器上安装 Redgate SQL Monitor 后,我们发现我们有很多阻塞的进程,有时会死锁。

使用 Redgate,我们意识到问题出在存储过程上。这是一个简单的存储过程,只是增加产品的查看次数(简单更新)

ALTER PROCEDURE [dbo].[SP_IncreaseProductView]
    @PID int 
AS
BEGIN
    UPDATE dbo.stProduct 
    SET ViewCount = ViewCount + 1 
    WHERE ID = @PID
END

当该存储过程关闭时,一切都很好,但有时块过程错误又回来了。

此table(产品)没有任何触发器。但它就像系统的核心,有 12000 条记录。

它有 3 个索引,1 个集群索引和 2 个非集群索引,还有很多统计信息

我们没有任何交易。块过程主要发生在更新查询中。

如何找出问题出在哪里?

抱歉我的语言不好

谢谢

编辑:

我认为问题不在于 SP,而是关于产品 table 的更新(这是我的意见)。它很大 table。当 SP 关闭但更少时,我仍然得到块进程。 我们有很多 select 并更新此 table。

我还用 LINQ to SQL 重写了增加观看次数,但仍然像打开 SP 时一样进行阻止处理。

编辑 2:

我设置了分析器并获取了关于产品 table 的所有查询。 530 select(大多数与另外 2 table 连接)和每分钟 25 次更新(仅限产品 table)。

目前,[SP_IncreaseProductView] 已关闭。因为当它打开时,我们大约每 10 秒就会让块进程和操作超时,并且网站停止。

之后(将 SP 设置为关闭)块进程仍然存在,但每天大约 50 个。

预计:我想你有很多更新到单个小(12K 行)table。

您可以:

  1. 解决您的问题

    在你的 UPDATE

    中输入 ROWLOCK 提示

    将数据库选项更改为 READ_COMMITED_SNAPSHOT

    不过请注意:它可能会产生其他问题。

  2. 更复杂的方法来完全消除阻塞

    不适合胆小的人。

    创建 table dbo.stProduct_Increment.

    [SP_IncreaseProductView] 修改为 INSERT 为增量 table。

    创建UPDATE你的dbo.stProduct的周期性任务并清除增量table。

    创建组合 stProduct 和 stProduct_Increment 的视图。

    将 stProduct 的所有 SELECT 语句修改为创建的视图。

我会选择 Ingaz 的第二个解决方案,但可以执行进一步的优化或简化:

1) 在产品中存储浏览量 1:1 table. 这在某些查询不需要浏览量时特别有用

2) 观看次数冗余 - 在产品 table 中保留浏览量并从那里读取 - 还在另一个 table 中定义观看次数(仅 productid 和 viewcount 列) - 应用程序可以在第二个 table 中直接异步更新 - 根据第二个 table

的数据更新产品 table 中的作业

这确保锁定对产品的影响 table 远小于独立更新。