哪个更快:MAX()或IDENT_CURRENT?

bsi*_*vel -4 sql-server

哪个更快:Select Max(<IdentityKeyColumn>) + 1或者Select 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工作原理的细节.

Aar*_*and 9

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

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

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

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();
Run Code Online (Sandbox Code Playgroud)

(注意,seed_value并且last_value是类型SQL_VARIANT,因为IDENTITY列可以使用多种数字类型实现,因此这就是为什么@i不是INT那种情况.)

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

然而...

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

例如: