哪个更快:MAX()或IDENT_CURRENT?

时间:2013-04-16 16:37:45

标签: sql-server

哪个更快:Select Max(<IdentityKeyColumn>) + 1Select Ident_Current('<tablename>') +1

我有一个包含450万行的表,旧的存储过程使用: select @MaxID = Max(ID) + 1 from tablename

我想更新它以使用: Select @MaxID = ident_current('tablename') + 1

但是,我不确定ident_current从哪里获取表的最后一个标识值。是从master或msdb数据库中的系统表中查询还是对表的数据进行某种最大聚合?

我需要提出ident_current应该更快的案例,但我没有找到有关ident_current如何运作的详细信息。

1 个答案:

答案 0 :(得分:9)

据我所知,IDENT_CURRENT()用于检索当前标识值的实际方法没有记录。它可以使用您不允许运行的内部函数直接从内存中检索它。你可以想象它可能做了什么,并在某种程度上模拟它,例如

SELECT COALESCE(last_value, seed_value)
  FROM sys.identity_columns
  WHERE [object_id] = OBJECT_ID('dbo.tablename'));

您可以在系统上自行比较这样的代码:

SELECT SYSDATETIME();
GO
DECLARE @i INT = IDENT_CURRENT('dbo.tablename');
GO 10000
SELECT SYSDATETIME();
GO
DECLARE @i INT = (SELECT MAX(column) FROM dbo.tablename);
GO 10000
SELECT SYSDATETIME();
GO
DECLARE @i SQL_VARIANT = (SELECT COALESCE(last_value,seed_value)
  FROM sys.identity_columns
  WHERE [object_id] = OBJECT_ID('dbo.tablename'));
GO 10000
SELECT SYSDATETIME();

(请注意,seed_valuelast_value的类型为SQL_VARIANT,因为IDENTITY列可以使用多种数字类型实现,因此{{1}在这种情况下,{}不是@i。)

我的猜测是你不会在那里看到任何微不足道的差异,除了随着桌子越来越大INT方法需要更长的时间(这就是为什么我不打算发布我的结果)这个测试 - 我不知道你的表中有多少行,将用于MAX的索引有多宽,等等。您将不得不自己确定哪种方法在您的方案中更快,使用您的硬件和数据,或者它是否真的无关紧要。

无论其...

......正如我在评论中所说的那样,哪一个更快是无关紧要的,因为你首先使用的逻辑在任何一个之间做出决定是有缺陷的。插入行,使用MAXSCOPE_IDENTITY()子句获取值,然后继续。不要尝试游戏系统并预测最终会插入OUTPUT值,因为我保证 失败。这是不是一个假设 - 它已被证明过,过,过,过......

例如: