-4

哪个更快:Select Max(<IdentityKeyColumn>) + 1OR 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工作的详细信息。

4

1 回答 1

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_valueandlast_value是 type SQL_VARIANT,因为IDENTITY列可以使用许多数字类型来实现,所以这就是为什么在这种情况下@i不是 an INT。)

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

然而...

...正如我在评论中所说,其中哪个更快是无关紧要的,因为您首先使用的逻辑来决定它们中的任何一个是有缺陷的。插入行,使用SCOPE_IDENTITY()orOUTPUT子句获取值,然后继续。不要试图玩弄系统并预测IDENTITY最终会插入什么值,因为我向你保证这失败。这不是一个假设——它已经被证明了一遍又一遍,一遍又一遍……

例如:

于 2013-04-16T17:39:40.430 回答