【发布时间】:2016-06-13 10:11:12
【问题描述】:
我有一个包含以下代码的存储过程:
BEGIN TRY
--BEGIN TRANSACTION @TranName
DECLARE @ID int
INSERT INTO [dbo].[a] ([Comment],[Type_Id],[CreatedBy])
VALUES ('test',1,2)
SET @ID = SCOPE_IDENTITY()
INSERT INTO [dbo].[b] ([Can_ID],[Com_ID],[Cal_ID],[CreatedBy])
VALUES (1,@ID,null,2)
UPDATE c SET LastUpdated = GETDATE(), LastUpdatedBy = 2 WHERE b.id = @ID
--COMMIT TRANSACTION @TranName
SELECT * from [View] where a.id=@ID
END TRY
BEGIN CATCH
--ROLLBACK TRANSACTION @TranName
END CATCH
其中的每个语句都单独运行(就像现在一样)运行得很快。 但是当我们从 Transaction 的代码中删除 cmets 时,脚本的运行时间会从 1 秒增加到 2 分钟以上。
系统已经运行了很长一段时间了,之前这不是问题,我一直在尝试搜索有关 SQL Server 如何处理事务的文档,以防万一有任何可能影响 SQL 性能和我唯一想到的是事务日志……但理想情况下,这些单独的语句也可以在单独的事务中运行,有什么想法吗?
【问题讨论】:
-
这听起来像是一个锁定问题。让所有这些操作在事务中运行将导致您的会话在表 a、b 和 c 上保持锁定比在没有事务的情况下运行要长得多。您应该在运行期间查看服务器上的锁定和等待情况。
-
运行您的查询并在单独的窗口中运行此 DMV 并粘贴有问题的输出。从系统中选择 ec.blocking_session_id,ec.wait_type,ec.last_Wait_type,txt.text,pln.query_plan。 dm_exec_requests ec cross apply sys.dm_exec_sql_text (ec.sql_handle) txt cross apply sys.dm_exec_query_plan(ec.plan_handle) pln
-
感谢这些人,我会尽快检查它,因为目前我没有足够的权限来运行这些查询,一旦我会告诉你输出可以运行它们:)
-
这是一个伪造的脚本 UPDATE 和 SELECT 行不应该工作。请提供填写表格 A、B、C 的代码以及您的 [视图] 的代码。
-
脚本是原始脚本的副本,我只是修改了列并放置了一些虚拟数据。 Slava 原始表格和视图太大,无法将它们复制并粘贴到此处。我担心的不是我选择/更新/插入的数据,我担心的是当我用事务包围它们时,脚本的执行时间会增加很多。正如 Jens 建议的那样,我想我可能在某个地方有一把锁。
标签: sql-server stored-procedures sql-server-2012 sqlperformance sqltransaction