web-dev-qa-db-ja.com

シーケンスとアイデンティティ

SQL Server 2012では、OracleおよびPostgresと同じSequenceが新機能として導入されました。シーケンスはアイデンティティよりも優先されますか?そして、なぜシーケンスが必要なのでしょうか?

76
Sleiman Jneidi

答えが見つかると思います こちら

列のID属性を使用して、自動インクリメント番号(主キーとして頻繁に使用される)を簡単に生成できます。 Sequenceを使用すると、挿入中にテーブル列にアタッチできる別のオブジェクトになります。 IDとは異なり、列の値の次の番号はディスクからではなくメモリから取得されます。これにより、SequenceはIdentityよりも大幅に高速になります。これについては、今後の例で説明します。

そして ここ

シーケンス:シーケンスは、SQL Serverコミュニティから長年にわたって要求されており、このリリースに含まれています。シーケンスは、数値のシーケンスを生成するユーザー定義のオブジェクトです。シーケンスを使用した例を次に示します。

および ここ

SQL Serverシーケンスオブジェクトは、SQLテーブルのID列と同じように一連の数字を生成します。しかし、シーケンス番号の利点は、シーケンス番号オブジェクトが単一のSQLテーブルで制限されないことです。

また、msdnでは、使用法と必要な理由についても読むことができます( here ):

シーケンスは、シーケンスが作成された仕様に従って数値のシーケンスを生成するユーザー定義のスキーマバインドオブジェクトです。数値のシーケンスは、定義された間隔で昇順または降順で生成され、要求に応じて循環(繰り返し)する場合があります。 ID列とは異なり、シーケンスはテーブルに関連付けられていません。アプリケーションは、シーケンスオブジェクトを参照して、次の値を受け取ります。シーケンスとテーブルの関係は、アプリケーションによって制御されます。ユーザーアプリケーションは、シーケンスオブジェクトを参照し、複数の行とテーブルにわたって値キーを調整できます。

CREATE SEQUENCEステートメントを使用して、テーブルとは独立してシーケンスが作成されます。オプションにより、増分、最大値と最小値、開始点、自動再起動機能、およびキャッシュを制御して、パフォーマンスを向上させることができます。オプションの詳細については、CREATE SEQUENCEを参照してください。

行が挿入されるときに生成されるID列の値とは異なり、アプリケーションは、NEXT VALUE FOR関数を呼び出すことにより、行を挿入する前に次のシーケンス番号を取得できます。シーケンス番号は、番号がテーブルに挿入されない場合でも、NEXT VALUE FORが呼び出されたときに割り当てられます。 NEXT VALUE FOR関数は、テーブル定義の列のデフォルト値として使用できます。 sp_sequence_get_rangeを使用して、複数のシーケンス番号の範囲を一度に取得します。

シーケンスは、任意の整数データ型として定義できます。データ型が指定されていない場合、シーケンスはデフォルトでbigintになります。

70
Arion

シーケンスとIDはどちらも自動番号の生成に使用されますが、主な違いはIDはテーブルに依存し、シーケンスはテーブルに依存しないことです。

自動番号をグローバルに(複数のテーブルで)維持する必要があるシナリオがある場合、特定の番号の後に間隔を再起動する必要があり、パフォーマンスのためにそれをキャッシュする必要がある場合は、シーケンスが必要な場所です身元。

以下に、シーケンスの実世界の例、その実装、およびシーケンスと同一性の違いを定義する記事を示します。

http://raresql.com/2012/04/29/how-sequence-works-in-sql-server-2012/http://raresql.com/2012/05/01/IDとシーケンスの差/

19
user1059637

シーケンスはID列よりも柔軟性がありますが、パフォーマンス上の利点はありませんでした。

IDを使用したパフォーマンスは、バッチ挿入にシーケンスを使用した場合よりも一貫して3倍高速であることがわかりました。

約150万行を挿入しましたが、パフォーマンスは次のとおりです。

  • IDについては14秒
  • シーケンスの場合は45秒

テーブルのデフォルトを介してシーケンスオブジェクトを使用するテーブルに行を挿入しました。

NEXT VALUE for <seq> for <col_name>

また、selectステートメントでシーケンス値を指定しようとしました:

SELECT NEXT VALUE for <seq>, <other columns> from <table>

どちらも同一法よりも同じ要因でした。シーケンスにデフォルトのキャッシュオプションを使用しました。

Arionの最初のリンクで参照されている記事は、行ごとの挿入のパフォーマンスを示しており、IDとシーケンスの違いは、10,000個の挿入で16.6秒から14.3秒でした。

キャッシングオプションはパフォーマンスに大きな影響を与えますが、より大きなボリューム(+ 1M行)の方が識別は高速です

Utly4lifeのコメントによる詳細な分析については、これを参照してください link .

12
Stagg

私はこれが少し古いことを知っていますが、私に噛み付く観察を追加したかったです。

インデックスを順序どおりにするために、アイデンティティからシーケンスに切り替えました。後で、シーケンスがレプリケーションで転送されないことがわかりました。シーケンスが同期していないため、2つのデータベース間でレプリケーションをセットアップした後、キー違反が発生し始めました。あなたが決定を下す前に気をつけてください。

3
Ken

最近では、同一性とシーケンスについて考慮すべきことが少しありました。ギャップなしでアイデンティティを維持したい場合、MSFTがシーケンスを提案するようになりました。 IDに大きなギャップがある問題がありましたが、強調表示されたこのステートメントに基づいて、SQLがIDをキャッシュし、再起動後にそれらの番号を失ったという問題を説明できます。

https://docs.Microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property?view=sql-server-2017

サーバーの再起動またはその他の障害後の連続値-SQL Serverはパフォーマンス上の理由からID値をキャッシュする場合があり、割り当てられた値の一部はデータベース障害またはサーバーの再起動中に失われる可能性があります。これにより、挿入時にID値にギャップが生じる可能性があります。ギャップが許容できない場合、アプリケーションは独自のメカニズムを使用してキー値を生成する必要があります。 NOCACHEオプションを指定してシーケンスジェネレータを使用すると、コミットされないトランザクションのギャップを制限できます。

1
awilbourn

シーケンスの最適な使用法は、ID列を置き換えるのではなく、「注文番号」タイプのフィールドを作成することです。

言い換えると、注文番号はエンドユーザーに公開され、ビジネスルールが一緒にある場合があります。一意にする必要がありますが、ID列を使用するだけでも実際には正しくありません。

たとえば、異なる注文タイプでは異なるシーケンスが必要になる場合があるため、社内注文ではなく、インターネット注文のシーケンスを使用する場合があります。

言い換えれば、SequenceをIDの単純な置き換えと考えるのではなく、IDがビジネス要件に適合しない場合に役立つと考えてください。

0
Greg Gum