-4

どちらが速いですか: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ただし、テーブルの最後の ID 値をどこから取得するかはわかりません。master データベースまたは msdb データベースのシステム テーブルからクエリを実行するか、テーブルのデータに対して何らかの最大集計を実行しますか?

より高速なケースを作成する必要がありident_currentますが、どのように機能するかについての詳細は見つかりませんでしたident_current.

4

1 に答える 1

9

現在の ID 値を取得するために使用する実際の方法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@iINT

私の推測では、テーブルが大きくなるにつれてアプローチに時間がかかることを除いて、無視できるほどの違いは見られないでしょうMAX(そのため、このテストの結果をわざわざ投稿するつもりはありません - 方法がわかりません)テーブルに多くの行がある、に使用されるインデックスの幅MAXなど)。ハードウェアとデータを使用して、これらのアプローチのどちらがシナリオでより高速であるか、またはそれが本当に問題にならないかどうかを自分で判断する必要があります。

でも...

...コメントで述べたように、どちらが速いかは関係ありません。最初にそれらのいずれかを決定するために使用しているロジックに欠陥があるためです。SCOPE_IDENTITY()行を挿入し、 orOUTPUT句を使用して値を取得し、次に進みます。システムを操作して、最終的に挿入される値を予測しようとしないでください。IDENTITYこれ失敗することが保証されているからです。これは仮定ではありません- それは何度も何度も何度も証明されています...

例えば:

于 2013-04-16T17:39:40.430 に答える