シーケンス(日本語マニュアルでは「順序」)は、指定された間隔で順序数を取得するスキーマ・オブジェクトです。通常のシーケンスはデータベース内で一意に識別され、複数のセッション間でシーケンス値を取得する場合でも同一の値が返ることはありません。
SESSION SEQUENCEとは
SESSION SEQUENCEを作成すると、セッション内でのみ一意な値を返します。このシーケンスを作成するにはCREATE SEQUENCE文にSESSION句を指定します。SESSION SEQUENCEは一時テーブル(TEMPORARY TABLE)に対する一意制約などに使うことが想定されています。SESSION句を指定しない従来のシーケンスはGLOBAL SEQUENCEと呼ばれます。GLOBAL句を指定するか、省略すると従来のシーケンスが作成されます。GLOBAL SEQUENCEとSESSION SEQUENCEの作成にはどちらもCREATE SEQUENCEシステム権限が必要です。
SQL> CREATE SEQUENCE seq01 SESSION;
順序が作成されました。
SQL> SELECT seq01.NEXTVAL FROM DUAL;
NEXTVAL
----------
1
別のセッションでオブジェクトを確認すると、USER_OBJECTSビューやUSER_SEQUENCESビューにレコードがあることが確認できます。SESSION SEQUENCEを作成した場合はUSER_SEQUENCEビューのSESSION_FLAG列がYになります。シーケンス値を取得すると別のセッションで同じ値が取得されることがわかります。
SQL> SELECT SEQUENCE_NAME, SESSION_FLAG FROM USER_SEQUENCES;
SEQUENCE_NAME S
------------------------------ -
SEQ01 Y
SQL> SELECT seq01.NEXTVAL FROM DUAL;
NEXTVAL
----------
1
SESSION SEQUENCEの変更
SQLリファレンス・マニュアルには構文のみ記載されていて説明がありませんが、GLOBAL SEQUENCEとSESSION SEQUENCEは相互にタイプを変更できます。
シーケンスのタイプをGLOBALからSESSIONに変更した場合、シーケンス値の初期値はタイプを変更した時点の値になります。
SQL> CREATE SEQUENCE seq02 GLOBAL;
順序が作成されました。
SQL> SELECT seq02.NEXTVAL FROM DUAL;
NEXTVAL
----------
1
SQL> SELECT seq02.NEXTVAL FROM DUAL;
NEXTVAL
----------
2
SQL> SELECT seq02.NEXTVAL FROM DUAL;
NEXTVAL
----------
3
SQL> ALTER SEQUENCE seq02 SESSION;
順序が変更されました。
SQL> CONNECT SCOTT/TIGER
接続されました。
SQL> SELECT seq02.NEXTVAL FROM DUAL;
NEXTVAL
----------
4
マニュアルには記載はありませんが、ALTER SEQUENCE RESTART文によるシーケンス値のリセットは、実行したセッションでは無効になるようです。
SQL> SELECT seq02.nextval from dual;
NEXTVAL
----------
9
SQL> ALTER SEQUENCE seq02 RESTART;
順序が変更されました。
SQL> SELECT seq02.nextval from dual;
NEXTVAL
----------
10
パフォーマンス
デフォルト設定で作成したGLOBAL SEQUENCEとSESSION SEQUENCEでパフォーマンスを比較しました。
NEXTVALを100万回取得して時間を計測します。SESSIONシーケンスは通常のシーケンスよりも高速に処理が行われます。
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 sttime NUMBER;
3 loops NUMBER := 1000000;
4 num NUMBER;
5 BEGIN
6 sttime := DBMS_UTILITY.GET_TIME;
7
8 FOR i IN 1 .. loops LOOP
9 num := gseq.NEXTVAL;
10 END LOOP;
11
12 DBMS_OUTPUT.PUT_LINE('Global : ' || (DBMS_UTILITY.GET_TIME - sttime)/100.0 || ' secs');
13
14 sttime := DBMS_UTILITY.GET_TIME;
15
16 FOR i IN 1 .. loops LOOP
17 num := sseq.NEXTVAL;
18 END LOOP;
19
20 DBMS_OUTPUT.PUT_LINE('Session: ' || (DBMS_UTILITY.GET_TIME - sttime)/100.0 || ' secs');
21 END;
22 /
Global : 14.44 secs
Session: 5.63 secs
PL/SQLプロシージャが正常に完了しました。
設定 | 時間(秒) |
---|---|
GLOBAL | 14.44 |
SESSION | 5.63 |