sql - 很多查询被暂停。我应该怎么办?
问题描述
我正在处理大约 2000 人使用的应用程序。日常用户同时插入大约 300 行/用户(大约上午 7 点到上午 11 点)。我使用仅包含插入语句的存储过程来处理它,但我使用它begin tran
来防止主键重复。
当前挂起的事务经常发生,所以我的存储过程大约需要 1-2 分钟才能完成,这导致我们的用户等待很长时间才能插入每个数据。我已经检查过:
读取磁盘速度正常:600mb/s 写入 744mb/s。
10 个内核的处理器使用率在 20 - 40 % 之间。
内存使用只有6gb,我用了12gb的内存。
从
sys.dm_exec_requests
、sp_who2
和进行检查sys.dm_os_waiting_tasks
。数字 3 的结果是我发现我的存储过程相互挂起(相同的存储过程不同的执行程序)
这是我的存储过程(对不起,命名,因为它是我公司的机密):
ALTER PROC [dbo].[SP_DESTIONATION_TABLE_INSERT]
{params}
WITH RECOMPILE
AS
BEGIN
BEGIN TRAN InsertT
DECLARE @ERRORNMBR INT
SET @ERRORNMBR = 0
IF @T = ''
BEGIN
-------------------------------------------------
DECLARE @TCID VARCHAR(15)
SELECT @TCID = ID
FROM DESTIONATION_TABLE
WHERE NIK = @NIK AND
CUSTOMERID = @CUSTOMERID AND
CUSTOMERTYPE = @CUSTOMERTYPE AND --edit NvA 20180111
DATEDIFF(day,DATE,@DATE) = 0
--IF THERE IS ALREADY A CALL IN SERVER
IF @TCID IS NOT NULL
BEGIN
IF @INTERFACE <> 'WEB' BEGIN
--GET EXISTING CALL ID
SET @ID = @TCID
BEGIN TRAN UBAH
UPDATE DESTIONATION_TABLE
SET
columns=value
WHERE ID = @ID
AND employeeid = @employeeid
AND CUSTOMERID = @CUSTOMERID
SET @ERRORNMBR = @ERRORNMBR + @@ERROR
IF @ERRORNMBR = 0
BEGIN
COMMIT TRAN UBAH
SELECT
columns
FROM DESTIONATION_TABLE WHERE ID = @ID
END
ELSE
BEGIN
ROLLBACK TRAN UBAH
END
END
COMMIT TRAN InsertT
RETURN
END
--------------------------------------------------
-- CHECK @DEVICECONTROLID
IF @DEVICECONTROLID IS NOT NULL
AND @INTERFACE <> 'WEB'
AND EXISTS(SELECT 1 FROM DESTIONATION_TABLE WHERE DEVICECONTROLID = @DEVICECONTROLID)
BEGIN
IF NOT EXISTS(SELECT 1 FROM DESTIONATION_TABLE_TEMP WHERE DEVICECONTROLID = @DEVICECONTROLID)
BEGIN
INSERT INTO DESTIONATION_TABLE_TEMP
(COLUMNS)
VALUES
(VALUES)
END
SELECT * FROM DESTIONATION_TABLE WHERE _DEVICECONTROLID = @_DEVICECONTROLID
END
ELSE
BEGIN
some logic to make primary key formula{string+date+employeeid+increment}
END
END
ELSE
BEGIN
BEGIN TRAN UBAH
IF @PARAMS = 'WEB'
BEGIN
UPDATE DESTIONATION_TABLE
SET
COLUMNS = PARAMS
WHERE ID = @ID
END
ELSE IF PARAMS = 'MOBILE'
BEGIN
UPDATE DESTIONATION_TABLE
SET
COLUMNS = PARAMS
WHERE ID = ID
END
SET @ERRORNMBR = @ERRORNMBR + @@ERROR
IF @ERRORNMBR = 0
BEGIN
COMMIT TRAN UBAH
SELECT
COLUMNS
FROM DESTIONATION_TABLE WHERE ID = ID
END
ELSE
BEGIN
ROLLBACK TRAN UBAH
END
END
COMMIT TRAN InsertT
END
我需要一个建议,接下来我应该检查什么以了解我的服务器出了什么问题。
是begin tran
这里的问题吗?
解决方案
我不是专家,但谷歌搜索“BEGIN TRAN”似乎表明它“锁定表,直到事务通过“COMMIT TRAN”提交......这意味着它是一个阻塞过程。所以如果你是当所有这些插入尝试执行时,表被锁定,其中一些显然不会成功。
我建议在它自己的线程上建立一个工作队列来监听 INSERTS/UPDATES。然后队列可以在空闲时清空到数据库中。
推荐阅读
- java - Java 停止 Windows 关机
- python - 连接 .mtx 文件并更改单元 ID 的计数器
- intellij-idea - 使用 WildFly 的 Java EE 7 EJB 身份验证 - 安全注释不起作用
- c - 在 C 中没有得到适当的持续时间
- firebase - Firestore 日期范围查询 - 当天搜索
- python - 尝试运行服务器时出现 Django 运行时错误
- sql - SQL Server:执行更新查询时,无法执行删除查询
- ios - 如何获得正确的夏令时缩写
- python - 为什么每次迭代后整列的值都会发生变化,而不仅仅是一个特定的单元格?
- sql - 使用 Spring JPA 检查集合中的完全匹配