3.11.1 CREATE INDEX形式1の形式と規則
(1) 機能
実表の一つ,又は複数の列にインデクスを定義します。
(2) 使用権限
- 表の所有者
-
公用RDエリアに自分が所有する表のインデクスを定義できます。
- 私用RDエリアの利用権限を持つ表の所有者
-
利用権限を持つ私用RDエリアに自分が所有する表のインデクスを定義できます。
(3) 形式1<インデクスの定義>
CREATE 〔UNIQUE〕 INDEX 〔認可識別子.〕インデクス識別子 ON 〔認可識別子.〕表識別子(列名〔{ASC|DESC}〕 〔,列名〔{ASC|DESC}〕〕…) 〔IN{RDエリア名 |(RDエリア名) |((RDエリア名)〔,(RDエリア名)〕…) |マトリクス分割インデクス格納用RDエリア指定}〕 〔インデクスオプション〕… マトリクス分割インデクス格納用RDエリア指定::=2次元格納用RDエリア指定 2次元格納用RDエリア指定::= (マトリクス分割用RDエリアリスト〔,マトリクス分割用RDエリアリスト〕…) マトリクス分割用RDエリアリスト::=(RDエリア名〔,RDエリア名〕…) インデクスオプション::={PCTFREE=未使用領域の比率 |UNBALANCED SPLIT |EMPTY |除外値指定} 除外値指定::=EXCEPT VALUES (NULL〔,NULL〕…)
(4) オペランド
(a) 〔UNIQUE〕
インデクスを定義するキー値(インデクスとして定義する一つ,又は複数の列の全体の値)が,すべての行で異なっている場合に指定します。
UNIQUEを指定して,インデクス作成,又は更新時に重複キー値を検出した場合,HiRDBがエラーを返します。ただし,ナル値を含むキー値の場合,重複した値があっても重複キーにはなりません。
UNIQUEを指定する場合は次の点に注意してください。
- 1. 表を横分割する場合
-
表を横分割する場合のUNIQUE指定可否を次の表に示します。
表3‒18 表を横分割する場合のUNIQUE指定可否 表の分割方法※1
UNIQUEを指定しようとするインデクスの構成列※2
インデクスの分割方法※4
UNIQUE指定可否
サーバ内の横分割
キーレンジ分割(マトリクス分割以外),及びFIXハッシュ分割
分割キーインデクス
表の分割数と一致
○
表の分割数と不一致
−
非分割キーインデクス
分割キーを含む(順不同)
表の分割数と一致
○
表の分割数と不一致(横分割しない)
○
分割キーを含まない(順不同)
表の分割数と一致
×
表の分割数と不一致(横分割しない)
○※3
フレキシブルハッシュ分割
該当しない
該当しない
×
マトリクス分割
分割キーインデクス
表の分割数と一致
○
表の分割数と不一致
−
非分割キーインデクス
分割キーをすべて含む場合(順不同)
表の分割数と一致
○
表の分割数と不一致
−
分割キーをすべて含まない場合(順不同)
表の分割数と一致
×
表の分割数と不一致(横分割しない)
−
サーバ間の横分割(サーバ内分割なし)
キーレンジ分割(マトリクス分割以外),及びFIXハッシュ分割
分割キーインデクス
表の分割数と一致
○
表の分割数と不一致
−
非分割キーインデクス
分割キーをすべて含む場合(順不同)
表の分割数と一致
○
表の分割数と不一致
−
分割キーをすべて含まない場合(順不同)
表の分割数と一致
×
表の分割数と不一致
−
フレキシブルハッシュ分割
該当しない
該当しない
×
マトリクス分割
分割キーインデクス
表の分割数と一致
○
表の分割数と不一致
−
非分割キーインデクス
分割キーをすべて含む場合(順不同)
表の分割数と一致
○
表の分割数と不一致
−
分割キーをすべて含まない場合(順不同)
表の分割数と一致
×
表の分割数と不一致
−
サーバ間の横分割(サーバ内分割あり)
キーレンジ分割(マトリクス分割以外),及びFIXハッシュ分割
分割キーインデクス
表の分割数と一致
○
表の分割数と不一致
−
非分割キーインデクス
分割キーをすべて含む場合(順不同)
表の分割数と一致(サーバ内でも分割)
○
表の分割数と不一致(サーバ内は非分割)
○
分割キーをすべて含まない場合(順不同)
表の分割数と一致(サーバ内でも分割)
×
表の分割数と不一致(サーバ内は非分割)
×
フレキシブルハッシュ分割
該当しない
該当しない
×
マトリクス分割
分割キーインデクス
表の分割数と一致
○
表の分割数と不一致
−
非分割キーインデクス
分割キーをすべて含む場合(順不同)
表の分割数と一致
○
表の分割数と不一致
−
分割キーをすべて含まない場合(順不同)
表の分割数と一致
×
表の分割数と不一致
−
- (凡例)
-
○:UNIQUEを指定できます。
×:UNIQUEを指定できません。
−:インデクスを定義できません。
- 注※1
-
サーバ内の横分割とは,HiRDB/シングルサーバでの横分割,又はHiRDB/パラレルサーバで一つのバックエンドサーバに閉じた横分割のことをいいます。
サーバ間の横分割とは,HiRDB/パラレルサーバで複数のバックエンドサーバにわたった横分割のことをいいます。なお,サーバ内の横分割とサーバ間の横分割が混在する場合は,サーバ間の横分割に分類します。表の横分割については,マニュアル「HiRDB システム導入・設計ガイド」を参照してください。
- 注※2
-
分割キーインデクスとは,表を横分割するときに格納条件を指定した列(分割キー)を第1構成列とするインデクスのことで,次のインデクスを指します。
- 単一列分割の場合:
-
分割キーに作成した単一列インデクス,又は分割キーを先頭とする複数の列に作成した複数列インデクス
- 複数列分割の場合:
-
分割キーを先頭とし,かつ分割に指定した列を先頭から同順にすべて含んでいて,複数の列に作成した複数列インデクス
- 注※3
-
ハッシュ分割表のリバランス機能使用時は×となります(RDエリアを追加してサーバ間分割に移行した場合に,UNIQUEが指定できなくなるため)。
- 注※4
-
インデクスの分割方法は,インデクス格納用RDエリアの指定方法に依存します。INオペランドを省略した場合は,フレキシブルハッシュ分割を除き,インデクスの分割方法が原因でUNIQUEを指定できなくなることはありません。INオペランドで明示的にインデクス格納用RDエリアを指定する場合には,UNIQUEを指定できないときがあるので注意してください。
- 2. 繰返し列を使用している場合
-
UNIQUEを指定したインデクスの構成列に,繰返し列を含むことはできません。
(b) 〔認可識別子.〕インデクス識別子
認可識別子には,作成したインデクスを所有するユーザの認可識別子を指定します。
インデクス識別子には,定義するインデクスの名称を指定します。
表所有者が定義した自分の所有するインデクス内に同じ名称は指定できません。
(c) 〔認可識別子.〕表識別子
認可識別子には,表を所有するユーザの認可識別子を指定します。
表識別子には,インデクスを作成する実表の名称を指定します。
(d) (列名〔{ASC|DESC}〕〔,列名〔{ASC|DESC}〕〕…)
- 列名
-
インデクスを定義する列の名称を指定します。
列名は最大64個指定できます。
列名を複数個指定する場合,同じ名称は指定できません。
- ASC
-
インデクスを昇順に定義する場合に指定します。
- DESC
-
インデクスを降順に定義する場合に指定します。
(e) IN
{RDエリア名 |(RDエリア名) |((RDエリア名)〔,(RDエリア名)〕…) |マトリクス分割インデクス格納用RDエリア指定}
マトリクス分割インデクス格納用RDエリア指定::=2次元格納用RDエリア指定
2次元格納用RDエリア指定::=(マトリクス分割用RDエリアリスト〔,マトリクス分割用RDエリアリスト〕…)
- マトリクス分割用RDエリアリスト::=(RDエリア名〔,RDエリア名〕…)
-
インデクスを格納するRDエリアの名称を指定します。
マトリクス分割インデクス格納用RDエリア指定は,マトリクス分割表にインデクスを定義する場合に指定します。RDエリア名の規則については,マトリクス分割以外の表と同じです。
インデクスを格納するRDエリアについての規則を次に示します。
-
RDエリア名は一時表用RDエリア以外のユーザ用RDエリアである必要があります。また,HiRDB/パラレルサーバでは次の制限があります。表識別子で指定した表が共用表の場合,RDエリア名は共用RDエリアでなければいけません。表識別子で指定した表が非共用表の場合,RDエリア名に共用RDエリアは指定できません。
-
RDエリアは,あらかじめデータベース初期設定ユティリティで作成,又はデータベース構成変更ユティリティで追加されていなければなりません。
-
RDエリア名を省略すると,表識別子で指定した表が格納されているRDエリアに格納されます。ただし,HiRDB/シングルサーバで表を分割した場合,又はHiRDB/パラレルサーバで同じバックエンドサーバ内で表を分割した場合,分割キー以外の列を先頭に指定したインデクスは,最初に分割条件を指定した表格納先RDエリアに格納されます。マトリクス分割表の場合,分割キーに指定したすべての列を,インデクス構成列の先頭から同順に指定しないときは,2次元格納用RDエリア指定を省略できません。
-
RDエリア名を複数個指定する場合,同じRDエリア名は指定できません。ただし,境界値指定の横分割表,ハッシュ分割表,又はマトリクス分割表で,表格納用RDエリア名が重複している場合は指定できます。
-
表が複数のRDエリアに分割して格納されている場合,インデクス格納用RDエリアの指定は次のようになります。
・分割キーインデクスの場合,RDエリア名は表を格納しているRDエリアと同じ数だけ指定します。このとき,インデクスの格納先はCREATE TABLEで指定した表格納用RDエリアの指定順に対応します。
・境界値指定の横分割表,ハッシュ分割表,又はマトリクス分割表で,表格納用RDエリア名が重複している場合は,それに対応するようにインデクス格納用RDエリア名を指定します。
定義例を次に示します。
1.格納条件による横分割の場合
2.境界値による横分割の場合
3.マトリクス分割の場合
-
HiRDB/パラレルサーバの場合,表を格納するRDエリアと対応するインデクスを格納するRDエリアは同じバックエンドサーバ内の必要があります。
-
非分割キーインデクスの場合のRDエリアの指定は次のようにしてください。
・インデクスをサーバ内横分割しない場合,RDエリア名は表を分割して格納しているサーバの数だけ指定します。HiRDB/パラレルサーバの場合,表があるバックエンドサーバごとに一つのRDエリアを指定します。HiRDB/シングルサーバの場合,一つ指定できます。ただし,マトリクス分割表の場合,分割キーインデクスのときと同じです。
・インデクスをサーバ内横分割する場合,RDエリア名は表を格納しているRDエリアと同じ数だけ指定します。このとき,インデクスの格納先はCREATE TABLEで指定した表格納用RDエリアの指定順に対応します。また,境界値指定の横分割表,ハッシュ分割表,又はマトリクス分割表で,表格納用RDエリア名が重複している場合は,それに対応するようにインデクス格納用RDエリア名を指定します。
なお,指定順は任意であり,同一サーバ上の表格納RDエリアに対応するインデクスが各々格納されます。
-
リバランス表を格納しているユーザ用RDエリアは指定できません。
-
リバランス表に対してインデクスを定義する場合は,RDエリア名を必ず指定してください。
-
(f) PCTFREE=未使用領域の比率
インデクス作成時のインデクスページ内の未使用領域の比率を指定します。未使用領域の比率は,0〜99(単位:%)を指定できます。省略すると,30%が仮定されます。仮定値は,システム共通定義のpd_ddl_idx_pctfreeオペランドで変更できます。pd_ddl_idx_pctfreeオペランドについては,マニュアル「HiRDB システム定義」を参照してください。
データベース作成ユティリティ及びデータベース再編成ユティリティでのインデクスの一括作成時に,未使用領域の比率でインデクスが作成されます。INSERT文やUPDATE文など,ほかの追加,及び更新ではPCTFREE=0が仮定されます。
インデクスを定義した後,行の追加が頻繁に発生する場合,未使用領域の比率を高く設定してください。
(g) UNBALANCED SPLIT
ページスプリットする場合,両ページに対するキーの振り分けを不均衡にします。
スプリット対象ページへのキーの追加位置が,ページの前半部の場合はスプリット後の左側のページの空きを多く確保し,後半部の場合は右側のページの空きを多く確保するように分割します。このようなインデクスをアンバランスインデクススプリットといいます。
アンバランスインデクススプリットについては,マニュアル「HiRDB システム運用ガイド」を参照してください。
(h) EMPTY
未完状態のインデクスを作成する場合に指定します。
EMPTYを指定すると,インデクスを定義するときの同時実行性を向上させることができます。また,表の格納データが多く,複数のインデクスの定義を同時に実行する場合に効果があります。表にデータが格納されていない場合は効果がありません。
EMPTYオプションの使用方法については,マニュアル「HiRDB システム運用ガイド」を参照してください。
(i) 除外値指定
ナル値だけで構成されるキー値を除いて,インデクスを定義します。
非ナル値制約の列を含む場合には,除外値指定は指定できません。また,除外値指定を指定した場合,データベース再編成ユティリティでインデクス順にアンロードできません。
除外値を指定したインデクスの構成列に,繰返し列を含むことはできません。
(5) 共通規則
-
インデクスは,一つの表に最大255個定義できます。
-
インデクスは,ナル値を含む列,又は行のない列に対しても定義できます。
-
インデクスは,次に示すデータ型の列では定義できません。
-
BLOB
-
BINARY
-
抽象データ型
-
-
インデクスを複数の列で構成する場合,項番3に加え,次に示すデータ型の列は指定できません。
-
FLOAT
-
SMALLFLT
-
-
インデクスを構成する列の長さの合計は,次の計算式を満たすようにしてください。
列の長さの合計≦
MIN((インデクス格納用RDエリアのページサイズ÷2)−1242,4036)
定義するインデクスが一時インデクスの場合は,一時表を実体化する際に上記を満たすかどうかをチェックします。
一時表の実体化については,マニュアル「HiRDB システム導入・設計ガイド」の「一時表」を参照してください。
インデクスを構成する各列の長さを次の表に示します。
表3‒19 インデクスを構成する列の長さ データ型
各列の長さの合計が255バイト以下の場合
各列の長さの合計が256バイト以上の場合
単一列インデクスを構成する列
複数列インデクスを構成する列
単一列インデクスを構成する列
複数列インデクスを構成する列
構成列が固定長だけの場合
構成列に可変長を含む
構成列が固定長だけの場合
構成列に可変長を含む
INTEGER
4
5
6
−
5
7
SMALLINT
2
3
4
−
3
5
DECIMAL〔(m〔,n〕)〕
↓m÷2↓+1
↓m÷2↓+2
↓m÷2↓+3
−
↓m÷2↓+2
↓m÷2↓+4
FLOAT
8
−
−
−
−
−
SMALLFLT
4
−
−
−
−
−
CHAR(n),MCHAR(n)
n1
n1+1
n1+2
n1
n1+1
n1+3
NCHAR(n)
2×n2
2×n2+1
2×n2+2
2×n2
2×n2+1
2×n2+3
DATE
4
5
6
−
5
7
TIME
3
4
5
−
4
6
TIMESTAMP
7+p÷2
8+p÷2
9+p÷2
−
8+p÷2
10+p÷2
INTERVAL YEAR TO DAY
5
6
7
−
6
8
INTERVAL HOUR TO SECOND
4
5
6
−
5
7
VARCHAR, MVARCHAR
n1+1
−
n1+2
n1+2
−
n1+3
NVARCHAR
2×n2+1
−
2×n2+2
2×n2+2
−
2×n2+3
- (凡例)
-
m,n:正の整数
n1:実際のデータ長
n2:文字数
p:小数秒精度
−:該当しません。
-
同じ列構成のインデクス(クラスタキー,主キーも含む)は,一つだけ定義できます。同じ列構成とは,次の条件をすべて満たすものをいいます。
-
列名の並び,及び列数が一致している
-
昇順,降順の指定がすべて一致している,又はすべて逆になっている
-
-
インデクスを定義しようとしている表に対して手続き及びトリガが定義されている場合,そのSQLオブジェクト中のインデクス情報は無効になります。この場合,トリガは実行できなくなります。また,手続きからこの手続き又はトリガは実行できなくなるため,SQLオブジェクトを再作成する必要があります。
-
同一のインデクスオプションは,繰り返して指定できません。
-
複数の繰返し列から構成されるインデクスを定義した場合,それらの繰返し列の現在要素数は同じにしてください。
-
実行中のSQLオブジェクト中のインデクス情報が無効になる場合,Java手続き中からCREATE INDEXは実行できません。
-
インデクスを格納するRDエリアに,インナレプリカ機能を適用しているRDエリアと適用していないRDエリアは混在して指定できません。インナレプリカ機能を適用しているRDエリアを指定する場合,RDエリア名にはオリジナルRDエリア名を指定します。
-
インナレプリカ機能を使用している場合のCREATE INDEXの実行条件については,マニュアル「インナレプリカ機能 HiRDB Staticizer Option」を参照してください。
-
一つのRDエリアに格納できるインデクスは,最大500個です。
-
インデクスの構成列に,予備列は指定できません。
-
一時インデクスを定義する場合,次の指定はできません。
-
格納用RDエリア名
-
EMPTY
-
-
SQLセッション固有一時表を使用しているSQLセッション中で,使用中のSQLセッション固有一時表に対してインデクスは定義できません。
(6) 留意事項
-
インデクスが付いている列の値をユーザが更新すると,インデクスも更新されます。
-
複数列インデクスを定義すると,各列の指定順位はキー値作成の指定順位になります。
-
単一列インデクスが定義されている列にも,複数列インデクスを定義できます。
-
CREATE INDEXは,OLTP下のX/Openに従ったUAPからは指定できません。
-
EMPTYを指定してインデクスを定義した場合,データベース再編成ユティリティでインデクスを再作成する必要があります。インデクスの再作成については,マニュアル「HiRDB コマンドリファレンス」を参照してください。
-
WITHOUT ROLLBACKを指定している表にインデクスを定義した場合の規則については,「CREATE TABLE(表定義)」のWITHOUT ROLLBACKの規則を参照してください。
-
除外値指定を指定したインデクスは,除外値の行が選択される可能性があるSQL文では使用されないので注意してください。
-
大量のデータが登録されている表に対してCREATE INDEX文でインデクスを作成する場合,処理時間が長くなるおそれがあります。CREATE INDEX文を実行する前に,タイマ監視に関する指定を次のように設定してください。
-
クライアント環境定義PDCWAITTIME
実績やデータ量からCREATE INDEXの実行時間を推測できる場合は,0以外の余裕を持たせた値を指定してください。
実行時間を推測できない場合は,0又は指定を省略してください。
-
-
HiRDB/パラレルサーバでサーバ間横分割した表にインデクスを定義する場合で,表格納用RDエリア,又は指定したインデクス格納用RDエリアが閉塞状態のときは,RDエリアの排他待ちとなります。このとき,排他待ちの時間がシステム定義pd_lck_wait_timeoutオペランドの指定値に達してタイムアウトしても,すぐにエラーリターンされないことがあります。これを避けるため,CREATE INDEX文を実行する前に,表格納用RDエリア,又は指定したインデクス格納用RDエリアの閉塞状態を解除してください。
(7) 使用例
-
在庫表(ZAIKO)の商品コード(SCODE)列に昇順のインデクス(IDX1)を定義します。ただし,インデクス定義後も行の追加が頻繁に発生すると仮定し,インデクスページ内の未使用領域の比率を50パーセントに指定します。
CREATE INDEX IDX1 ON ZAIKO(SCODE ASC) PCTFREE = 50
-
在庫表(ZAIKO)の商品名(SNAME)列と色(COL)列を組にして,複数列インデクス(IDX2)を定義します。このとき,インデクスをユーザ用RDエリア(RDA1)に格納します。
CREATE INDEX IDX2 ON ZAIKO(SNAME,COL) IN RDA1
-
在庫表(ZAIKO)の商品コード(SCODE)列に昇順のインデクス(IDX3)を定義します。このとき,インデクスをRDA1,RDA2,RDA3のRDエリアに分割して格納します。
ただし,在庫表は商品コードを分割キーにし,三つのRDエリアに分割して格納されているものとします。
CREATE INDEX IDX3 ON ZAIKO(SCODE) IN ((RDA1),(RDA2),(RDA3))