理解SQL Server查询执行和事务

3

我在SQL数据库方面有丰富的经验,但主要是在Oracle和MySQL上。

现在我正在处理SQL Server 2012(Management Studio 2008),并遇到了一个我无法解释的奇怪行为。

考虑以下三个查询和一个由400k行组成的源表:

SELECT ID_TARJETA 
INTO [SGMENTIA_TEMP].[dbo].[borra_borra_] 
FROM [DATAMART_SEGMENTIA].[DESA].[CLIENTES]

ALTER TABLE [SGMENTIA_TEMP].[dbo].[borra_borra_] 
  ADD PRIMARY KEY (ID_TARJETA)

SELECT COUNT(*) 
FROM [SGMENTIA_TEMP].[dbo].[borra_borra_]

如果我一个接一个地运行它们,它就可以正常运行(总计:约7秒)。

如果我选择它们全部一起运行,它会运行得很慢(总计:约60秒)。

最后,如果我用一个事务来包装它,它又可以正常运行。

BEGIN TRANSACTION;

SELECT ID_TARJETA 
INTO [SGMENTIA_TEMP].[dbo].[borra_borra_] 
FROM [DATAMART_SEGMENTIA].[DESA].[CLIENTES]

ALTER TABLE [SGMENTIA_TEMP].[dbo].[borra_borra_] 
ADD PRIMARY KEY(ID_TARJETA)

SELECT COUNT(*) 
FROM [SGMENTIA_TEMP].[dbo].[borra_borra_]

COMMIT;

整个情景对我来说毫无意义,考虑到创建交易看起来相当昂贵,第一个场景应该是慢的,而第二个场景应该表现得更好,我错了吗?
这个问题对我非常重要,因为我正在通过编程(JDBC)构建此类查询包,并需要一种方法来调整其性能。

请在“查询选项”->“高级”对话框中检查“SET STATISTICS IO”和“SET STATISTICS TIME”。此外,请查看实际执行计划。 - dean
1个回答

0
两个提供的片段之间唯一的区别是第一个使用默认事务模式,而第二个使用“显式事务”。
由于SQL Server的默认事务模式是“自动提交事务”,每个单独的语句都是一个事务。
您可以在这里找到有关事务模式的更多信息。
您可以尝试这个,看看它是否在60秒内运行:
BEGIN TRANSACTION;

SELECT ID_TARJETA 
INTO [SGMENTIA_TEMP].[dbo].[borra_borra_] 
FROM [DATAMART_SEGMENTIA].[DESA].[CLIENTES];

COMMIT;

BEGIN TRANSACTION;

ALTER TABLE [SGMENTIA_TEMP].[dbo].[borra_borra_] 
ADD PRIMARY KEY(ID_TARJETA);

COMMIT;

BEGIN TRANSACTION;

SELECT COUNT(*) 
FROM [SGMENTIA_TEMP].[dbo].[borra_borra_]

COMMIT;

没有问题,这与事务有关。但是为什么如果我依次执行一个查询(3个事务),它们运行得非常好(7秒添加它们各自的时间),而如果我选择同时选择+执行它们(1个事务?)它运行得非常慢(60秒)? - Ivan Arrizabalaga
@IvanArrizabalaga 处理3个事务而不是一个似乎是一个很好的原因。考虑执行BEGIN TRANSACTION / COMMIT 3次而不是1次。 - dario

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接