哪个更快: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
如何运作的详细信息。
答案 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_value
和last_value
的类型为SQL_VARIANT
,因为IDENTITY
列可以使用多种数字类型实现,因此{{1}在这种情况下,{}不是@i
。)
我的猜测是你不会在那里看到任何微不足道的差异,除了随着桌子越来越大INT
方法需要更长的时间(这就是为什么我不打算发布我的结果)这个测试 - 我不知道你的表中有多少行,将用于MAX
的索引有多宽,等等。您将不得不自己确定哪种方法在您的方案中更快,使用您的硬件和数据,或者它是否真的无关紧要。
......正如我在评论中所说的那样,哪一个更快是无关紧要的,因为你首先使用的逻辑在任何一个之间做出决定是有缺陷的。插入行,使用MAX
或SCOPE_IDENTITY()
子句获取值,然后继续。不要尝试游戏系统并预测最终会插入OUTPUT
值,因为我保证 将 失败。这是不是一个假设 - 它已被证明过,过,过,过......
例如: