作为零售结账流程的一部分,有一个事务性存储过程,它从18个表中选择每个表,并将它们插入到单独的数据库中,以供以后的大型机处理。此过程显示了一些奇怪的计时行为,我认为这是因为对SQL Server中事务工作方式的根本误解。
我认识到这不是解决这个问题的最佳架构,新的解决方案正在开发中,但同时,我需要改进这个过程。
存储过程根据用户请求运行,如下所示:
BEGIN TRANSACTION
INSERT INTO Table1
(Column1,
Column2,
Column3,
Column4,
Column5,
Column6,
Column7,
Column8)
SELECT
Column1,
Column2,
Column3,
Column4,
Column5,
Column6,
Column7,
Column8
FROM
OLTPTable T
INNER JOIN
LookupTable1 L
ON
T.Foreign = L.Key
INSERT INTO Table2
(Column1,
Column2,
Column3)
SELECT
Column1,
Column2,
Column3
FROM
OLTPTable2 T
INNER JOIN
LookupTable2 L
ON
T.Foreign = L.Key
INSERT INTO Table3
(Column1,
Column2,
Column3,
Column4,
Column5,
Column6)
SELECT
Column1,
Column2,
Column3,
Column4,
Column5,
Column6
FROM
OLTPTable3 T
INNER JOIN
LookupTable3 L
ON
T.Foreign = L.Key
-- Through Table 18 and OLTP Table 18
COMMIT TRANSACTION日志记录如下所示:
Table1 0.2 seconds 354 rows
Table2 7.4 seconds 35 rows
Table3 3.9 seconds 99 rows在行的数量或连接的复杂度与时间之间没有明确的相关性。
我的问题是-在这样一个漫长的过程中,交易的影响是什么?子选择中的所有表在开始时都被锁定了吗?一次一个?它是否在等待源表可用于锁,这是导致等待的原因?
发布于 2011-06-28 01:01:32
在什么隔离级别下?
对于写部分(插入部分),无论隔离级别如何,一切都是一样的:所有插入的行都以X模式锁定,直到事务结束。行锁可以escalate到表锁。
如果隔离级别保留为默认的读取提交快照,并且数据库上的read-committed-snapshot-isolation选项处于OFF状态,则会发生如下情况:每次选择都会以S模式锁定一行,然后立即释放它。
在repeatable read隔离下,由SELECT获取的S锁将一直保留到事务结束,并且它们可能升级为表S锁。
在serializable read隔离下,SELECT将获取范围锁而不是行锁,并将它们保留到事务结束。同样,可能会发生锁升级。
在snapshot isolation下,SELECTs根本不获取任何锁(忽略模式稳定性锁的一些技术细节),它们将从版本tore中读取任何锁定的行。读取的版本对应于事务开始时的值的快照。
在read committed isolation下,如果在数据库上启用了read-committed-snapshot-isolation,那么SELECTs将不会获得任何锁,如果行被锁定,它们将从版本存储中读取。读取的版本对应于语句开头的值的快照。
现在回到您的问题,为什么您会看到性能上的差异?与任何性能问题一样,最好应用调查方法,而Waits and Queues是一个很好的方法。一旦您调查了根本原因,就可以提出适当的解决方案。
发布于 2011-06-28 00:27:26
使用默认的READ COMMITTED隔离级别,读(共享)锁将仅在每个SELECT期间存在。不是为了交易。
要改变这一点,您需要更高级别的REPEATABLE_READ来保持共享(读)锁,直到事务结束。
备注:
您的插入持续时间将受到一大堆条件的影响。其中一些:
对于要作为目标表上的INSERT
日志文件:
编辑:
经过深思熟虑后,您是否会更好地使用sp_getapplock等来维护应用程序级别的并发。
发布于 2011-06-28 00:39:43
在我看来,在这种情况下,使用或不使用事务并不会对性能产生太大影响。我建议您需要分别调优每个insert (考虑到insert的性能不仅取决于子选择,还取决于insert-目标表中的索引越多,insert性能就越差;您还可能为某些表选择了错误的聚集索引)。
https://stackoverflow.com/questions/6495736
复制相似问题