事务块会降低SQL Server的性能吗?

如何解决事务块会降低SQL Server的性能吗?

| 现在,我和一个同事正在争论非重要的BEGIN TRAN ... COMMIT TRAN块的影响。 我已经为简单的插入-更新-删除操作编写了约140个存储过程,由于以后我们可能需要在其中进行一些额外的操作,因此我已经包括了可能必要的BEGIN TRAN和COMMIT TRAN块,所以:
CREATE PROCEDURE [Users].[Login_Insert]

        @Username           nvarchar (50) OUTPUT,@Password           char (40),@FullName           nvarchar (150),@LoginTypeId        int

AS

SET NOCOUNT ON;

BEGIN TRY
BEGIN TRAN

INSERT [Users].[Login]
(
        [Username],[Password],[FullName],[LoginTypeId]
)
VALUES
(
        @Username,@Password,@FullName,@LoginTypeId
)

COMMIT TRAN
RETURN 1
END TRY

BEGIN CATCH
ROLLBACK TRAN

RETURN -1
END CATCH

GO
现在,其中许多交易可能不再需要。这些多余的块会以明显的方式影响性能吗? 提前致谢。     

解决方法

        还不足以引起注意。 也就是说,每个TXN将在BEGIN TRAN和INSERT之间打开一个额外的OhNoSecond。如果有人可以衡量我,我会印象深刻。 但是,如果您进行了BEGIN TRAN,然后提示用户输入,则您的腿需要折断... 不过好主意:我这样做是为了使我所有的写过程都是100%一致的,具有相同的错误处理,可以嵌套等 编辑:在Remus回答之后,我看到我没有链接到我的嵌套TXN模板:包含TRY CATCH ROLLBACK模式的嵌套存储过程?这与Remus \'的不同之处在于,它总是回滚并且没有SAVEPOINTs 编辑,一个快速而肮脏的测试显示它在进行交易时的速度大约是2/3
SET NOCOUNT ON
SET STATISTICS IO OFF

DECLARE @date DATETIME2
DECLARE @noTran INT
DECLARE @withTran INT

SET @noTran = 0
SET @withTran = 0

DECLARE @t TABLE (ColA INT)
INSERT @t VALUES (1)

DECLARE 
  @count INT,@value INT

SET @count = 1

WHILE @count < 100
BEGIN

  SET @date = GETDATE()
  UPDATE smalltable SET smalltablename = CASE smalltablename WHEN \'test1\' THEN \'test\' ELSE \'test2\' END WHERE smalltableid = 1
  SET @noTran = @noTran + DATEDIFF(MICROSECOND,@date,GETDATE())

  SET @date = GETDATE()
  BEGIN TRAN
  UPDATE smalltable SET smalltablename = CASE smalltablename WHEN \'test1\' THEN \'test\' ELSE \'test2\' END WHERE smalltableid = 1
  COMMIT TRAN
  SET @withTran = @withTran + DATEDIFF(MICROSECOND,GETDATE())

  SET @count = @count + 1
END

SELECT 
  @noTran / 1000000. AS Seconds_NoTransaction,@withTran / 1000000. AS Seconds_WithTransaction

Seconds_NoTransaction    Seconds_WithTransaction
2.63200000               2.70400000
2.16700000               2.12300000
反转更新顺序可以保持相同的行为     ,        在您发布的代码中,没有可测量的效果,但是事务确实对性能有影响,由于日志刷新提交分组,它们可以显着提高性能,或者由于管理不当的争用问题,它们可以显着降低性能。但最重要的是,当需要交易以确保正确性时,您不能跳过拥有它们。话虽这么说,相对于事务和try-catch块,您的模板实际上是非常糟糕的。 catch块中的事务必须具有三态逻辑检查
XACT_STATE
返回值(-1、0、1),并正确处理注定的事务。有关示例,请参见异常处理和嵌套事务。 同样,永远不要将try-catch错误处理与返回代码错误处理混合使用。选择一个并坚持下去,最好是赶上。换句话说,您的存储过程应提高,而不返回-1。将异常与错误代码混合在一起会使代码成为维护和正确调用的噩梦。     ,        TL; DR-存储的Procdure包含两个处理3300万条记录的选择查询,我花了45秒钟执行,而没有事务处理,花了48秒钟。 免责声明:我编写了一个存储过程大约4个小时,并且遇到了一个对该问题的可衡量的答案(注意:这并不重要!)由于我正在处理的数据的敏感性,故意省略了查询逻辑中的空白用。 方法:此过程是使用两个查询开发的-一个执行大部分繁重的工作,另一个查询自行计算一个额外的字段,因此它不会尝试计算超出所需范围的更多字段。我将其分为两个步骤: 1)我用1个SQL SELECT编写了2个Common Table Expressions到一个临时表中,然后再次对其进行查询。我之所以必须这样做,是因为要求我实现的是几个标量值函数,否则它们将尝试在超过3,300万条记录(而不是355条)上运行该函数。 2)我在第一个查询之后附加了一个标量值函数,因此它不会尝试查找3000万条记录(如果您愿意的话,它会带来很大的不同)。 查询:出于读者的目的,我剪切了大部分查询(case语句)。
CREATE PROC GET_PAYMENT_SUMS_BY_CLIENT
AS

--Required for reporting in a specific Business Intelligence later; Optional
SET FMTONLY OFF; 

BEGIN TRANSACTION

--Query 1
--This CTE checks over 30 million records
WITH CTE1 AS(
SELECT CASE VARIABLE
--170 case conditions go here
END AS TheType,Amount,PK1 FROM TABLE1),--THIS CTE Pivots the sums to get the data in the style I want it in
CTE2 AS(
SELECT PK1,[PIVOT1],[PIVOT2],[PIVOT3]
FROM
  (SELECT * FROM CTE1) AS BaseTable --Alias was just to get it to execute
)
PIVOT(
  SUM(Amount)
FOR TheType IN ([PIVOT1],[PIVOT3])
        ) AS PivotTable
    )
 )

SELECT TABLE2.NAME,CTE2.* INTO #TEMPORARY_TABLE 
FROM CTE2 
JOIN TABLE2 ON CTE2.PK1 = TABLE2.PK2

--Query 2
--Written to force the function to look at 355 records instead of 33 million
SELECT *,dbo.SCALAR_VALUED_FUNCTION(PK2) FROM #TEMPORARY_TABLE

COMMIT TRANSACTION
发现: 使用事务处理-如果使用事务处理逻辑,则从该集合产生的查询将花费48秒来处理包含170行的case语句中的超过3,300万条记录,按总和旋转数据,将数据放入临时表中并附加第一个查询运行后的标量值函数。 不使用事务-如果对代码中的注释行进行注释,则所有上述步骤将在45秒内完成。这比使用事务块快大约7%:3/45 = 0.0666 ....〜快7%。 结论: 尽管我的工作无法告诉您对10条记录进行相同的查询是否会产生相同比例的差异,但是它可以告诉您,当您开始使用更大的数据集和/或更复杂的查询时,它会变得越来越重要。 我知道这些信息对某个人有用!     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?